in reply to Re^17: Reusing a complex regexp in multiple spots, escaping the regexp
in thread Reusing a complex regexp in multiple spots, escaping the regexp

Thanks for the clarification. °

Honestly, when injecting code evaluation into a variable interpolation, I'm not surprised to get inconsistent side effects.

It would be of bigger concern if it also happened with more "official" means like (?{...}) or (??{...})

Cheers Rolf
(addicted to the Perl Programming Language :)
see Wikisyntax for the Monastery

°) how popular are Perl builds without thread support?

Replies are listed 'Best First'.
Re^19: Reusing a complex regexp in multiple spots, escaping the regexp
by dave_the_m (Monsignor) on Apr 17, 2026 at 15:29 UTC
    The "code injection" was just a quick and dirty demonstration of a side-effect. Its shows that on a threaded build, the expression which defines the pattern is assembled each time, but then thrown away unused apart from the first iteration. Think for example of a tied array. The following:
    for my $i (0,1) { /abc$tied_array[$i]/; }
    will, on threaded builds, invoke both $tied_array->FETCH(0) and $tied_array->FETCH(1), but will discard the second value.

    Dave.

      Thanks for the better example!

      Does this double execution also effect officially embedded (?{CODE}) ?

      Shouldn't this be just documented with /o or (in a better world) even better emitting a warning?

      I'm using side effects in regexes mainly for debugging.

      On a tangent: My system Perl seems to be with thread support, I dunno how often Perl is even installed or used without thread support.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery

        On unthreaded builds, after the pattern has been assembled and compiled once, the op tree is modified so that on subsequent executions, all the assembly ops are skipped. On threaded builds, all the assembly ops are still executed. but once it reaches the op which compiles the regex, it notices that the regex is flagged as already compiled, throws away all the accumulated strings on the stack which make up the body of the stack, and uses the pre-compiled regex.

        Literal patten code blocks are compiled once at the same time the surrounding code is compiled, not when the pattern is compiled.

        Its a bug which needs fixing. The whole /o implementation is a bit rubbish at the moment.

        Dave.