in reply to ??{ } oddity

Code in ??{ .. } is executed to produce a subexpression that then is tested to see if there is a match.

In your case this means that if the subexpression matches, the m// match is done and the code is not called again.

If it doesn't match, the expression is moved forward by one character and tries to match again (which calls the code again, because if you use a code block, you'll likely want to return a different match expression).

It's very likely you can use a more efficient technique here, but that depends on what you actually want to do.

Replies are listed 'Best First'.
Re^2: ??{ } oddity
by insaniac (Friar) on Apr 28, 2005 at 12:41 UTC
    ah ok, thanks!

    a friend of mine asked me this question (well, actually he asked how he could execute a piece of code, well actually call a method, in a m//. i made the method return a static value, but it will mostly likely do something else..)

    he gave me a theoretical example of what he was trying... so i don't really know what his intentions were. I just found the ??{ } expression in perldoc perlre.

    but thanks for the answer, i understand the behaviour now

    to ask a question is a moment of shame
    to remain ignorant is a lifelong shame

      A regex is a double-quote-ish expression, so variables are interpolated, including dereferencing references. Any block of code can be stuck in place of a reference (it should return a reference, in order to dereference properly). So you can execute any code you want within a regex or a string. The result of the block will be dereferenced and interpolated into the string (here I return a ref to an empty string, so the pattern isn't changed):

      It will be executed each time the regex is looked at (compiled), even if the match doesn't get that far. For example:

      for (qw{dog pig cat horse}) { /.o${print "$_ gets printed\n";\''}/ and print "$_ matched\n"; } __END__ dog gets printed dog matched pig gets printed cat gets printed horse gets printed horse matched
      Contrast that with (?{}), which executes arbitrary code if the expression matched up to that point (and does not insert anything into your pattern):
      for (qw{dog pig cat horse}) { /.o(?{print "$_ gets printed\n"})/ and print "$_ matched\n"; } __END__ dog gets printed dog matched horse gets printed horse matched
      And finally (??{}), which acts the same, but does insert into your pattern:
      for (qw{dog pig cat horse}) { /.o(??{print "$_ gets printed\n"; 'g'})/ and print "$_ matched\n"; } __END__ dog gets printed dog matched horse gets printed
      The latter two are "experimental" features, but ref interpolation is not.

      Caution: Contents may have been coded under pressure.
        yeah, i needed the insert one ;-)
        thanks for the explanation of the differences..

        to ask a question is a moment of shame
        to remain ignorant is a lifelong shame