Skip to content

Conversation

mauke
Copy link
Contributor

@mauke mauke commented Aug 28, 2025

  • s///e is not limited to expressions. The replacement part can contain any number of statements, like do { ... }.
  • s///ee does not treat the RHS as a string. The RHS is parsed as a block (like s///e), but then the resulting string is eval()d.
  • You can have more than two es. Each additional e wraps another eval() around the result.

  • This set of changes does not require a perldelta entry.

- s///e is not limited to expressions. The replacement part can contain
  any number of statements, like 'do { ... }'.
- s///ee does not treat the RHS as a string. The RHS is parsed as a
  block (like s///e), but then the resulting string is eval()'d.
- You can have more than two e's. Each additional 'e' wraps another
  eval() around the result.
@book
Copy link
Contributor

book commented Aug 28, 2025

If it behaves as a do {} block, does that means there is a scope limited to the replacement part? And that each extra /e creates a new enclosing scope?

@mauke
Copy link
Contributor Author

mauke commented Aug 29, 2025

If it behaves as a do {} block, does that means there is a scope limited to the replacement part?

Yes:

use v5.36;

sub Honk::DESTROY {
    say "$_[0] destroyed";
}

my $string = "hello";
$string =~ s{([eo])}{
    say "replacing '$1'";
    my $obj = bless {}, 'Honk';
    "_"
}eg;

say "done: $string";
say '$obj is ', eval('$obj') // "not in scope: $@";

Output:

replacing 'e'
Honk=HASH(0x6140b77d4418) destroyed
replacing 'o'
Honk=HASH(0x6140b77d4418) destroyed
done: h_ll_
$obj is not in scope: Global symbol "$obj" requires explicit package name (did you forget to declare "my $obj"?) at (eval 1) line 1.

And that each extra /e creates a new enclosing scope?

Only in the sense that every eval() creates a runtime scope for the code it compiles, but I'm not sure what practical difference it would make.

Copy link
Contributor

@khwilliamson khwilliamson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This p.r. is a huge improvement IMO

to be C<eval>ed.

That is, C<s/FOO/BAR/e> will compute the replacement string at match time as if
by C<do { BAR }> (see L<perlfunc/do BLOCK>). Each additional C<e> modifier
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "by" here confuses me. Maybe "as if it had been written as"

That is, C<s/FOO/BAR/e> will compute the replacement string at match time as if
by C<do { BAR }> (see L<perlfunc/do BLOCK>). Each additional C<e> modifier
wraps a call to C<eval> around the result: C<s/FOO/BAR/ee> will compute the
replacement string as if by C<eval(do { BAR })>, C<s/FOO/BAR/eee> as if by
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, the by doesn't sound good to me

result.
e Evaluate the right side as a block of code.
ee Evaluate the right side as a block of code, then eval()
the resulting string.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where exactly in the source code does this evaluation of the RHS as a block of code rather than as either an expression or a string is enforced? (I'm asking this not to quibble, but just to know your reference point.)

@book
Copy link
Contributor

book commented Sep 3, 2025

  • You can have more than two es. Each additional e wraps another eval() around the result.

And I wrote a perfect example years ago:

use strict;my$s=';pop';$_='';# 59 /e, © 2001 Philippe "BooK" Bruhat
*_=*ARGV;@_=qw(4a4a2bfe01ac410d0105f4fd0dae30150dfab448f90208fa0d98
pop print+chr(shift) print+chr(shift) unshift@_,(shift()+shift())x2
push@_,(pop,pop)x24 ; unshift@_,(map{unpack'c',$_}split//)[0..25] ;
s/../chr(hex$&)/eg $_=substr(shift,0,52) @_=map{s|$|$s|s;$_}@_;pop)
;s//$s/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants