http://www.perlmonks.org?node_id=95775

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

Consider:

#!/usr/bin/perl -w use strict; my $match= "hi"; my $re= qr/($match)/; print "\$match is $match\n"; print "'chimp' matches (", 'chimp' =~ $re, ")\n"; $match= "lo"; print "\$match is $match\n"; print "'slow' matches (", 'slow' =~ $re, ")\n"; print "'chimp' matches (", 'chimp' =~ $re, ")\n";
produces
$match is hi 'chimp' matches (hi) $match is lo 'slow' matches () 'chimp' matches (hi)
So why does the qr// operator support the /o option? It already appears to only compile the regex once even without /o.

        - tye (but my friends call me "Tye")

Replies are listed 'Best First'.
Re: qr//o ... "o"??
by japhy (Canon) on Jul 11, 2001 at 22:14 UTC
    The "error" was in toke.c at S_scan_pat:
    STATIC char *
    S_scan_pat(pTHX_ char *start, I32 type)
    {   
        PMOP *pm;
        char *s;
    
        s = scan_str(start,FALSE,FALSE);
        if (!s)
            Perl_croak(aTHX_ "Search pattern not terminated");
    
        pm = (PMOP*)newPMOP(type, 0);
        if (PL_multi_open == '?')
            pm->op_pmflags |= PMf_ONCE;
        if(type == OP_QR) {
            while (*s && strchr("iomsx", *s))
                pmflag(&pm->op_pmflags,*s++);
        }
        else {
            while (*s && strchr("iogcmsx", *s))
                pmflag(&pm->op_pmflags,*s++);
        }
        pm->op_pmpermflags = pm->op_pmflags;
        
        PL_lex_op = (OP*)pm;
        yylval.ival = OP_MATCH;
        return s;
    }
    
    Getting rid of the "o" fixed it.

    japhy -- Perl and Regex Hacker
Re: qr//o ... "o"??
by particle (Vicar) on Jul 11, 2001 at 21:49 UTC
    tye~

    print the re, this might give you a clue:

    my $match= "hi"; my $re= qr/($match)/; print "\$match is $match\n"; print "\$re is $re\n"; $re= qr/($match)/io; print "\$re is $re\n"; $match= "lo"; $re= qr/($match)/; print "\$re is $re\n";
    prints~
    $match is hi $re is (?-xism:(hi)) $re is (?i-xsm:(hi)) $re is (?-xism:(lo))
    so 'o' is not really supported, it's masked. for some reason, you can put it in the expression and it won't complain.

    ~Particle

    nevermind the xp, remember the experience.

Re: qr//o ...
by japhy (Canon) on Jul 11, 2001 at 21:38 UTC
    It's silly that it should accept the /o modifier (and thus that it is documented to). I should patch that...

    japhy -- Perl and Regex Hacker
      #why is it silly? for my $match ("hi","lo"){ my $re= qr/($match)/o; print "\$match is $match\n"; print "'chimp' matches (", 'chimp' =~ $re, ")\n"; print "'slow' matches (", 'slow' =~ $re, ")\n"; }
      What? You patch Perl? Send it in and it sometimes gets accepted? How? Which version of Perl do you patch?
Re: qr//o ... "o"??
by japhy (Canon) on Jul 14, 2001 at 18:34 UTC
    Ugh, I'm so silly. Even after I learned what /o does at YAPC, from Dominus. I0's example answers the question.

    As for what /o does, it means "do not compile this again." What it does get that done is this:
    print "trying...\n"; $x = qr/japhy/o; print $you =~ $x; # makes a tree like [print "trying\n"] [compile regex /japhy/] [return regex (some internal form)] [match regex on $you] [print] # the /o modifier tells [return regex] to MODIFY the tree [print "trying\n"] -------------------\ [compile regex /japhy/] | [return regex (some internal form)] <-/ [match regex on $you] [print]
    That's what happens. The op-tree is modified because of the /o modifier. Perl never sees the "compile this regex" op again, and instead, it uses some pre-compiled regex.

    japhy -- Perl and Regex Hacker