in reply to Is this a bug ?

From perlop:

If the PATTERN evaluates to the empty string, the last successfully matched regular expression is used instead.

This isn't obvious (or often useful) behavior, but it's documented behavior. You can subvert this with a regex assertion such as a comment:

if ($r =~ /(?#avoid empty pattern)$r2/) { ... }

It's not a CGI bug. It's an insufficient encapsulation bug with regard to Perl 5 itself.

Replies are listed 'Best First'.
Re^2: Is this a bug ?
by ikegami (Patriarch) on Jul 12, 2011 at 20:46 UTC

    Is (?#...) recent? Alternatives:

    /(?:)$pat/ /(?:$pat)/ my $re = qr/$pat/; /$re/

      I'd always used (?:) before, but I'd forgotten how to spell it and found (?#) in the Perl 5.14 documentation. I couldn't find it in a modern perldelta though.

Re^2: Is this a bug ?
by i5513 (Pilgrim) on Jul 13, 2011 at 08:01 UTC
    Hi,

    Now I have the code here, and I tried to apply another logical solution (your solution works!), but it don't work, do you know where is my fail now ?

    My original code was:

    sub casa_ruta { my ($r, $ruta,$exactly)=@_; # avoid empty patern # if (length ($ruta) == 0) # { # $ruta="."; # } if (defined $exactly) { if ($r eq $ruta) { return 1; } } else { if ($r =~ /$ruta/i) { return 1; } } return 0; }
    Then, after reading your comment and manual I propose next solution:
    sub casa_ruta { my ($r, $ruta,$exactly)=@_; if ("r" =~ /(r)/) { ; } else { print STDERR "BUG\n"; } #print STDERR "$fix_re"; # if (length ($ruta) == 0) # { # $ruta="."; # } if (defined $exactly) { if ($r eq $ruta) { return 1; } } else { if ("r" =~ /(r)/) { ; } else { print STDERR "BUG2\n"; } if ($r =~ /$ruta/i) { return 1; } else { printf STDERR "BUG ('$r','$ruta')\n"; printf STDERR join (",",caller); exit 1; } } return 0; }

    But It print in STDERR :

    BUG ('/my/path','')

    My::Module,/path/to/myfile.pm,1181

    and exits

    Effectively with /(?:)$ruta/i it is working ... but I would like to understand this issue

    UPDATE:

    See my next debug trace:

    DB<1> c 152 ... #my script output here main::ejecutar_sae_appfinder(/srv/www/sae_appfinder/index.pl:152): 152: %nodos_tomcats=buscar_ruta_tomcats ($p_ruta,\%apaches, +\%tomcats,$search_tomcathost); DB<2> s Sae::Inventario::buscar_ruta_tomcats(/opt/scripts/perl/Sae/Inventario. +pm:1181): 1181: my ($ruta,$apaches,$tomcats,$search_tomcathost)=@_; DB<2> c casar_ruta Subroutine Sae::Inventario::casar_ruta not found. DB<3> c casa_ruta Sae::Inventario::casa_ruta(/opt/scripts/perl/Sae/Inventario.pm:91): 91: my ($r, $ruta,$exactly)=@_; DB<4> x @_ 0 '' 1 '' DB<5> n Sae::Inventario::casa_ruta(/opt/scripts/perl/Sae/Inventario.pm:94): 94: if ("r" =~ /(r)/) 95: { DB<5> p "$r" =~ /$ruta/ 1<label><input type="radio" name="format" value="html" checked="checke +d" />html</label><label><input type="radio" name="format" value="odt" + />odt</label><br><input type="submit" name="consultar" value="consul +tar" /><div><input type="hidden" name=".cgifields" value="info" /><i +nput type="hidden" name=".cgifields" value="format" /><input type="h +idden" name=".cgifields" value="entorno" /></div></form></div> DB<6> p "$r" =~ /$ruta/ 1 DB<7> n Sae::Inventario::casa_ruta(/opt/scripts/perl/Sae/Inventario.pm:108): 108: if (defined $exactly) 109: { DB<7> p "$r" =~ /$ruta/ DB<8>

    In DB<5> html code is printed here (If I add in the begin of script "$|=1;" it doesn't appear If I understand TFM "r" =~ /(r)/ should make $xx =~ // return true, isn't it?

    See null reply in DB<7> which is different than 1 in DB<6>
    Thanks!
      ok, so I reread the doc, and I understand it. With my proposed solution, i was using "/(r)/" pattern, so it was not working.
      It is not very intuitive, but it is ok
      Sorry wasting your time and a big thank for you

        Sorry wasting your time and a big thank for you

        I didn't actually help, but You learned about The empty pattern // and improved your bug report abilities -- not a waste of time :)