Damian Conway wrote on 03 December 2002 05:13
> -----cut----------cut----------cut----------cut----------cut-----
> 
> use re 'eval';
> 
> our $quoted  = qr/ ' (?: \\. | [^'] )*? '       # Match 'str'
>                   | " (?: \\. | [^"] )*? "       # Match "str"
>                   /x;
> 
> our $element = qr/ (?: [^'"{,]+                 # Match 
> non-special characters
>                       | \\.                      # Match 
> escaped anything
>                       | $quoted                  # Match 
> quoted anything
>                       | (??{$nested})            # Match {...,...,...}
>                     )+
>                   /xs;
> .....

Im a little curious about the need for the 

  use re 'eval';

in this example. Obviously it needs it under 5.6 but from what I can tell of
the documentation it shouldn't.  

The docs that I mean is the following bit of the documentation for (?{}) in
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 the re manpage), or the variables
contain results of qr// operator (see qr/STRING/imosx in the perlop
manpage).

It seems to me that according to this rule the 'eval' pragma shouldnt need
to be invoked as these rules are all in qr//'s.  

So is it a bug that these need the pragma, or is the documentation buggy for
not explaining the subtleties in more detail?

For instance why should the below snippet work fine without the pragma but
Damians doesn't?

A confused,
Yves

#!perl
my $str="1 2 3 10 6 7 8 11 12 13 14 15 161";

print "Before : $str\n";

# we use qr to avoid the use re 'eval';
my $rex=qr/(\d+)                      # match a number put it in $1
           (?{$num=$1})               # set $num to be $1
           (?:                        # dont capture all of this,
             \s+                      #  must have space between the numbers
             (                        #  capture into buffer $2
               (??{'\b'.++$num.'\b'}) #   match only the successor of $num
             )                        #  end of buffer
           )+                         # one or more
         /x;
$str=~s/$rex/$1-$2/g;      # and now substitute in

print "After  : $str\n";
__END__


Reply via email to