Say, you have a function, which takes a string, a pattern, and then matches the pattern to the string, but with a twist; a (fixed) code fragment is inserted:

sub example { my ($str, $pattern) = @_; $str =~ /$pattern(?{ 1; })/; }

The code block here is trivial, because it's not about the content of the block, just about its existence.

The above doesn't work, because by default you cannot interpolate a string in a pattern containing code blocks. So, you have to use re 'eval'; :

sub example { my ($str, $pattern) = @_; use re 'eval'; $str =~ /$pattern(?{ 1; })/; }

Now, that works, but that works a bit too well for my liking - it would now run code blocks if they are passed in using $pattern . This is not what I want. The following seems to fix that:

sub example { my ($str, $pattern) = @_; no re 'eval'; $pattern = qr /$pattern/; use re 'eval'; $str =~ /$pattern(?{ 1; })/; }

This dies if $pattern contains a (?{ code }) block. Except that it doesn't die when $pattern is already a compiled pattern - that's deemed safe. So, we need an additional stringification:

sub example { my ($str, $pattern) = @_; no re 'eval'; $pattern = "$pattern"; $pattern = qr /$pattern/; use re 'eval'; $str =~ /$pattern(?{ 1; })/; }

This does what I want it to do: run the code block, but die if $pattern contains a code block, regardless whether it's passed as a string or a compiled regexp.

But I wonder, is there a less cluncky way?