-
Notifications
You must be signed in to change notification settings - Fork 560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unexpected return values for multiple regexps in a single statement #19058
Comments
This could be a bug but is likely a stack issue related to the dynamic scope of the number variables. Generally you should only expect them to be set correctly in the full statement directly after the one containing the |
Thanks for your fast answer! The question I have is when and in what order the sub-statements are evaluated and why they are not handled separately. I'm not sure if this is really a bug, but it's unlike anything I thought I knew about perl. Maybe the issue can be shown more clear by defining an array containing two separate regexps matches. Here again, if I assign the values to a copy, it works: Even if $1 is somehow reused, I would expect the array elements to be matched and evaluated sequentially from left to right. |
Basically within a single statement, direct use of |
In other words, |
Thank you very much! This helps me a lot to understand why it works the way it does. |
This has nothing to do with
It "works" with double-quoted values because the string interpolation reads the value immediately and returns a temporary with a copy of it as it was at the time. |
In a way this is similar to how using a variable in the same expression where auto-increment is also used on it leads to undefined behavior. https://perldoc.perl.org/perlop#Auto-increment-and-Auto-decrement |
The OP's concerns appear to have been addressed. Is this ticket closable? Is some documentation change warranted? |
On Wed, 18 Aug 2021 at 02:43, Leon Timmermans ***@***.***> wrote:
This is because of how the magic of $ works. The second regex updates it
before the concatenation has actually happens. This is unfortunate, but
arguably not a bug.
But that also means equally it arguably *is* a bug. :-) [ if its arguable
its arguable, its not definitive ]
I just think its a "won't" fix bug that is unfortunate but not worth
fixing. But I would definitely consider it a bug and if in a future perl
the behavior changed to start doing the expected thing then I'd be happy
and argue it should be viewed as a bug fix and not a behavior change.
I mean think we generally would agree that:
$x= (EXPR_X);
$y= (EXPR_Y);
$x . $y
should produce the same result as
(EXPR_X) . (EXPR_Y)
leaving aside various scenarios where we document that it wont, it seems
unfortunate that
$x= ( $str1 =~ /($pat)/ && $1 );
$y= ( $str2 =~/($pat)/ && $1 );
$z= $x.$y
doesn't result in the same thing as:
$z= ($str1=~/($pat)/ && $1) . ($str2=~/($pat)/ && $1);
I mean I can imagine a world where we realize that we are putting a regex
capture var on the stack and resolve it then and there when we do so, which
would fix this. If this isnt a bug then that fix wouldn't be allowed.
So I argue this IS a bug.
Yves
…--
perl -Mre=debug -e "/just|another|perl|hacker/"
|
On Tue, Aug 24, 2021 at 10:02:30AM -0700, Yves Orton wrote:
leaving aside various scenarios where we document that it wont, it seems
unfortunate that
$x= ( $str1 =~ /($pat)/ && $1 );
$y= ( $str2 =~/($pat)/ && $1 );
$z= $x.$y
doesn't result in the same thing as:
$z= ($str1=~/($pat)/ && $1) . ($str2=~/($pat)/ && $1);
I mean I can imagine a world where we realize that we are putting a regex
capture var on the stack and resolve it then and there when we do so, which
would fix this. If this isnt a bug then that fix wouldn't be allowed.
So I argue this IS a bug.
I really don't see it as any different than using any other variable
multiple times, with modification in between:
my $i = 1;
my ($x, undef, $y) = ($i, $i=10, $i);
print "$x $y\n"; # prints 10 10
and comes under the general rubric of 'undefined behaviour'.
…--
The warp engines start playing up a bit, but seem to sort themselves out
after a while without any intervention from boy genius Wesley Crusher.
-- Things That Never Happen in "Star Trek" #17
|
I think we can close this? Any objections |
The doc team (are they still about?) might want to verify that the underlying concept here is clearly documented wherever it needs to be. But in respect of perl's behaviour I think this is closable. |
Unfortunately, no.
Agreed; closing. |
Description
When combining capture group values $1 from multiple regexps,
$1 returns the contents of the last regexp for all regexps.
Steps to Reproduce
perl -e 'use strict; use warnings; my $c = ("a" =~ m/(a)/ && $1) . ("b" =~ m/(b)/ && $1); print "$c\n";'
Output:
bb
Expected behavior
The first regexp should return "a" because the string "a" contains the character "a".
The second regexp should return "b" because the string "b" contains the character "b".
The stringing together of the values should result in "ab" and not in "bb".
It will work if you force the copying of the values of "$1"
perl -e 'use strict; use warnings; my $c = ("a" =~ m/(a)/ && "$1") . ("b" =~ m/(b)/ && "$1") ; print "$c\n";'
output:
ab
If you capture the values directly without access through $1, it will work, too. Here join is used to force the context of the list.
perl -e 'use strict; use warnings; my $c = join("", ("a" =~ m/(a)/) , ("b" =~ m/(b)/) ) ; print "$c\n";'
output:
ab
Perl configuration
The text was updated successfully, but these errors were encountered: