-
Notifications
You must be signed in to change notification settings - Fork 577
goto out of a block resets the last successful match when it should not. #21605
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
Comments
Can you provide a useful definition of "get lost"? |
Sure: |
I've tested it using:
The output is consistent going back to 5.8.9; i.e. this hasn't worked right since at least 5.8.9 (and possibly never). (However, I can't reproduce it like this using |
Just for completeness and for those who are allergic to PerlMonks, here's the original example:
The question is why |
@mauke: This is certainly the erroneous behavior I reported.
|
@jo-37 That example matches my expectations since match variables are dynamically scoped, so leaving the scope of the successful match makes them disappear. |
@mauke: Please take a deeper look at my example script. Replacing the inner block containing the
|
For completeness, here is a one-liner using
|
Not a bug. When the loop exits the match state is reset. Consider this reformulation of the code:
It prints 'x' because $& is bound to the last successful match in scope. A successful match behaves much like a local declaration. When the scope exits the localization is undone. It is morally equivalent to how $s behaves in the following:
|
@choroba wrote:
Because when there is no last successful match in the current scope the pattern is treated as being the empty string. In the most recent Perl release I added ${^LAST_SUCCESSFUL_PATTERN}, which you can use to check what is going on.
The only bug I see in this thread is the one reported by @mauke, rewritten here to use ${^LAST_SUCCESSFUL_PATTERN}.
The goto out of the scope shouldn't clear the pattern, it should be the same as it would be if the goto was removed. But I think that deserves its own ticket. I am closing this ticket, as not a bug. |
Actually i will leave it, and just rename it. |
But why does the behaviour change, when
That's a crucial point: |
Some one-liners using
vs.
Only with |
Ah, I see. You are assuming that the behavior of the loop without next is normative, and that the behavior with next is the exception, but as far as I can tell it is the opposite; it appears the localized match state isn't undone correctly when the next is omitted. Off the top of my head id assume its some kind of "optimization" that is actually breaking code. The following is wrong, ${^LAST_SUCCESSFUL_PATTERN} should be from the /x/ pattern at the top of the loop each time.
Adding a next as the last statement of the loop fixes it:
Compare with a true local which behaves correctly both ways:
|
What a twist! Thanks for clarification. But doesn't this mean there is a bug with both |
What about #21607, then? |
To make sure we have the same understanding of the whole problem, I'd like to summarize the findings. Using
After the Using
Here the behaviour for Is this correct? |
Yes, agreed.
I don't really like this way of looking at things as it depends on what I consider to be undefined behavior; that // should match the empty string if there is no last successful match. But leaving that aside, yes, I think so. Seems to me a simpler way to understand this is to say that the following two programs should behave the same, and the one with next is correct:
|
Just as a data point, pp_next() and other major scope exit functions
like pp_leave(), pp_leavesub() etc call cx_popblock() or cx_topblock(),
which both restore PL_curpm to the saved value.
On the other hand, a for loop where the code reaches the bottom, does a
pp_unstack(), which frees the argument, temps and save stacks, but
*doesn't* restore PL_curpm.
As to why this is, I have no idea.
…--
"You're so sadly neglected, and often ignored.
A poor second to Belgium, When going abroad."
-- Monty Python, "Finland"
|
Description
This bug was detected by @choroba and there is a related discussion at perlmonks.
The "empty pattern"
//
and$&
provide the last successfully matched pattern and string. Both get lost when jumping out of a block in several ways. Examples arenext
andgoto
.The example below uses
goto
for a convenient way to switch between "jump out of a block" and "no jump out of a block".next
without an inner block produces similar results.After the first successful match, the "empty pattern" and
$&
behave as expected. A "out-of-block-jump" then clears both, making//
an always matching genuine empty pattern and undefining$&
.Steps to Reproduce
Expected behavior
Annotated output from above script, note "ERROR":
Perl configuration
Should be reproducible with more recent perl versions, too.
The text was updated successfully, but these errors were encountered: