http://qs321.pair.com?node_id=11136455

almr has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks

it's never been quite clear to me how to get full -E behavior with a stdin script. Let's call perl from a shell script (this the reason for not wanting -E, and some other choices):

perl -Mv5.12 -wn -- - /etc/passwd <<'EOF' next unless / ([^:]*) : [^:]* : ([0-9]+) /x; my ($w, $n) = (uc $1, 5000 + $2); say qq{log=$w id=$n} EOF

As I understand it, -E turns on optionals (e.g. say, <<>>), but also some behaviors (e.g. use strict, Unicode handling). Now the unpalatable choices become

Are there any other options to get -E behavior without -E?

Replies are listed 'Best First'.
Re: -E behavior with stdin script (updated x2!)
by haukex (Archbishop) on Sep 05, 2021 at 07:42 UTC

    Note -E doesn't turn on strict, AFAICT its equivalent is -Mfeature=:all.

    Update: Sorry, that's not quite right - :all also enables experimental features and features that were removed from feature bundles of later versions, like array_base. I showed a slightly hackish workaround here.

    Update 2: Here's an improved version that gives exactly the same result as the -E switch:

    use Config; use feature ":$Config{PERL_REVISION}.$Config{PERL_VERSION}";

      Ah. I was getting confused. So the least-verbose choices become, I think,

      • [-Mstrict] -Mfeature=:all -- - <<EOF to run a stdin script
      • [-Mstrict] -E script to run a stringified script
      • -Mv5.28 {-e script | -- -} (as of now) to require a recent perl with all security & unicode fixes, turn on strict, and run either a stdin or a stringified script.
        The least verbose option would be -MMyDefaults, where you write a module named MyDefaults that sets all the bits as you prefer and then you install that on each system you use :-)
        -Mfeature=:all

        Sorry, I made a mistake, that's actually not exactly equivalent to -E, please see the updates in my node above.

Re: -E behavior with stdin script
by salva (Canon) on Sep 05, 2021 at 11:51 UTC
    AFAIK, there is no way to pick the features enabled by -E automatically other than by using it.

    But you can require just what you need inside the code chunk:

    perl -wn -- - /etc/passwd <<'EOF' use feature 'say'; next unless / ([^:]*) : [^:]* : ([0-9]+) /x; my ($w, $n) = (uc $1, 5000 + $2); say qq{log=$w id=$n} EOF
    That's the most future-proof solution.
      AFAIK, there is no way to pick the features enabled by -E automatically other than by using it.

      Well, -E is equivalent to a use feature ':5.XX';, so one slightly hackish way to get the same effect is use feature ":5.".(0+substr($],2,3));.

      Update: Crossposting the following better solution from my other node for completeness:

      use Config; use feature ":$Config{PERL_REVISION}.$Config{PERL_VERSION}";
Re: -E behavior with stdin script
by BillKSmith (Monsignor) on Sep 05, 2021 at 12:58 UTC
    The module Modern::Perl addresses a similar issue. I do not know if you could use it, but its documentation may be helpful.
    Bill
Re: -E behavior with stdin script
by ikegami (Patriarch) on Sep 05, 2021 at 19:15 UTC

    You really shouldn't be using -E outside of throwaway single-use code.

    The problem with -E is that it's not forward-compatible. It defies the whole feature mechanism by enabling the highest possible feature set, breaking programs the feature mechanism is supposed to protect.

    It's great for throwaway single-use code, but not for production code. You should use the appropriate feature set and/or version for your program. -M5.010 / use 5.010; would suffice for the posted example (although all higher versions that exist at this time would also work).

    Seeking work! You can reach me at ikegami@adaelis.com

Re: -E behavior with stdin script
by Anonymous Monk on Sep 05, 2021 at 14:31 UTC