Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Spurious re 'eval'; warning ?

by bsb (Priest)
on Aug 24, 2003 at 09:32 UTC ( #286177=perlquestion: print w/replies, xml ) Need Help??

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

If I'm understanding this correctly (and that's a BIG "if"), then the "Eval-group ..." warning should not appear.
$ perl -Mre=eval -e '/ (??{ "(?{1})" }) $_ /x' Eval-group not allowed at runtime, use re 'eval' in regex m/(?{1})/ at + -e line 1.
It seems like the 'eval' hint doesn't reach the right scope at the right phase, but this is so out of my depth I'm getting the bends.

Brad

PS. These all work as I understand "use re qw/eval/" except the third:

$ perl -e '/ (?{1}) $_ /x' Eval-group not allowed at runtime, use re 'eval' in regex m/ (?{1}) / + at -e line 1. $ perl -Mre=eval -e '/ (?{1}) $_ /x' # This is the odd one $ perl -Mre=eval -e '/ (??{ "(?{1})" }) $_ /x' Eval-group not allowed at runtime, use re 'eval' in regex m/(?{1})/ at + -e line 1. $ perl -Mre=eval -e '/ (??{ qr"(?{1})" }) $_ /x'

Replies are listed 'Best First'.
Re: Spurious re 'eval'; warning ?
by diotalevi (Canon) on Aug 24, 2003 at 14:01 UTC

    The error indicates the regex compiler didn't think it had everything it needed to create the regex complete with eval contents at compile time. The first thing here is that your inclusion of $_ defers the overall regex compilation time until runtime due to interpolation. At that point its just a distinction between whether "(?{1})" is precompiled or not for (??{ ... }).

    My guess is that you managed to stave off the runtime-eval error by tricking perl with the qr// operator. In reality that qr// wasn't compiled until the contents of the (??{ ... }) were being parsed/compiled at runtime. The difference is probably that the (?{1}) was considered safe by qr// because it was during *a* compiletime. That really doesn't sound like a correct behaviour to me. Bug?

      My guess is that you managed to stave off the runtime-eval error by tricking perl with the qr// operator

      Maybe. Although putting another eval string around it doesn't seem to change anything:

      $ perl -Mre=eval -e '/ (??{ eval "qr<(?{1})>" }) $_ /x' $ perl -Mre=eval -e '/ (??{ eval "q<(?{1})>" }) $_ /x' Eval-group not allowed ...
      perlre has an explicit distinction for interpolating qr// objects (under (?{}) instead). The problem is that I do use re "eval", but perl seems to forget. It does seems a little bug-ish, I'll perlbug it.

      perlre: (?{ })
      For reasons of security, this construct is forbidden if the regular expression involves run-time interpolation of variables, unless the perilous "use re 'eval'" pragma has been used (see re), or the variables contain results of "qr//" operator (see "qr/STRING/imosx" in perlop).

        And of course, the bug would be that perl isn't throwing the error but should.

      Date: 27 Aug 2003 12:47:56 -0000 From: Rafael Garcia-Suarez (via RT) Subject: Re: [perl #23569] use re 'eval'; lost in (??{"(?{1})"}) Brad Bowman (via RT) wrote: > This code generates an "Eval-group ..." error despite the presense > of "use re qw(eval)". > > $ perl -Mre=eval -e '/ (??{ "(?{1})" }) $_ /x' > Eval-group not allowed at runtime, use re 'eval' in regex m/(?{1})/ +at -e line 1. This is apparently just another instance of the compiler hints not bei +ng propagated to eval-strings (except "integer", "strict refs" and a few others). This can't be fixed non-kludgily without an overhaul of the h +int system.
Re: Spurious re 'eval'; warning ?
by CombatSquirrel (Hermit) on Aug 24, 2003 at 10:41 UTC
    I'm far from considering myself well-informed on RegEx matters, but the way I see it, the RegEx engine expects real code in (?{ code }) and (??{ code }) constructs and not a RegEx. See perlre for further reference. The reason why the fourth example works would then be that you told the compiler the 'code' was a RegEx. Just use one alternative at a time and you'll be fine.
    Hope this helped, CombatSquirrel.

    P.S.: What are you trying to do with your code? I don't see the sense of embedding one of the above constructs into the other. Maybe we can find a work-around if you give specifics of your problem.
      What are you trying to do with your code?

      I'm just playing around.

      Returning a qr// regex is a work around.

      I read perlre and re, and I consider "(?{1})" a valid return value. You can use other strings without a problem:

      $ id|perl -nle 'print /( (??{ q[uid=\d+] }) )/x' uid=1000
      This snippet from perlre doesn't specify a regex ref or string (although it is pretty vague). The example which follows in the man page uses a recursive qr// definition (so does return a qr// object).

      From perlre:
      (??{ code })
      ... The result of evaluation is considered as a regular expression and matched as if it were inserted instead of this construct.

        My apologies, seems as though you were right. However, I found an interesting section in perl5005delta:
        %s: Eval-group not allowed at run time
        (F) Perl tried to compile a regular expression containing the (?{ ... }) zero-width assertion at run time, as it would when the pattern contains interpolated values. Since that is a security risk, it is not allowed. If you insist, you may still do this by explicitly building the pattern from an interpolated string at run time and using that in an eval(). See perlre/(?{ code }).
        Perl just doesn't seem to like what you're doing and stops it ;-).
        Hope this helps.
        Cheers, CombatSquirrel.

        Update: fixed typos.
Re: Spurious re 'eval'; warning ?
by Anonymous Monk on Apr 24, 2013 at 22:27 UTC
    Why does this work?: perl -e '$_ = "The brown fox jumps over the lazy dog ABC god yzal eht revo spmuj xof nworb ehT";while(/(.{10,41})(?{$cap = $^N;$rev = r($cap);})(...)(??{$rev})/ig){print("$1\n")}sub r {return(join("",reverse(split("",$_[0]))))}' But not this?: perl -e '$_ = "The brown fox jumps over the lazy dog ABC god yzal eht revo spmuj xof nworb ehT";$f=10;$e=41;while(/(.{$f,$e})(?{$cap = $^N;$rev = r($cap);})(...)(??{$rev})/ig){print("$1\n")}sub r {return(join("",reverse(split("",$_[0]))))}' Please forgive me if the answer is already here. I'm feeling pretty scatter-brained today. Thanks, Rob

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2019-10-23 23:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?