Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

-E behavior with stdin script

by almr (Sexton)
on Sep 05, 2021 at 07:04 UTC ( [id://11136455]=perlquestion: print w/replies, xml ) Need Help??

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

  • specify a "minimal minimum" version (e.g. -Mv.5.12) to get say and strict; but that probably disables post-5.12 changes
  • specify a "maximal minimum" version (e.g. -Mv5.28), but that fails for older Perls
  • use -E with an inline single- / double-quoted shell string, with all the niceties of shell quoting / escaping
  • use -E with a wastefull -E "$(cat <<"EOF" ... )"

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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11136455]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2024-04-19 10:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found