You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Description
When lexical subs (my sub) that close over outer lexicals are used in subs that are recursive, weird things happen. It looks like Perl doesn't realize that the inner sub is a closure and has to be allocated at runtime (once per level of recursion). Instead Perl just reuses the same inner sub, overwriting its bindings.
Attempt 1:
outer(2): \&inner = CODE(0x55c73e8332b0)
inner(before): $x = 2 at SCALAR(0x55c73e87c180)
outer(1): \&inner = CODE(0x55c73e8332b0)
inner(before): $x = 1 at SCALAR(0x55c73e8121a0)
outer(0): \&inner = CODE(0x55c73e8332b0)
inner(before): $x = 0 at SCALAR(0x55c73e833370)
inner(after): $x = 0 at SCALAR(0x55c73e833370)
inner(after): $x = 0 at SCALAR(0x55c73e833370)
inner(after): $x = 0 at SCALAR(0x55c73e833370)
Attempt 2:
outer(2): \&inner = CODE(0x55c73e8332b0)
inner(before): $x = 2 at SCALAR(0x55c73e87c180)
outer(1): \&inner = CODE(0x55c73e833340)
inner(before): $x = 1 at SCALAR(0x55c73e8121a0)
outer(0): \&inner = CODE(0x55c73e833640)
inner(before): $x = 0 at SCALAR(0x55c73e833388)
inner(after): $x = 0 at SCALAR(0x55c73e833388)
inner(after): $x = 1 at SCALAR(0x55c73e8121a0)
inner(after): $x = 2 at SCALAR(0x55c73e87c180)
Expected behavior
"Attempt 1" is the broken case. Note in particular that all three levels of outer recursion seem to share the same inner sub (\&inner = CODE(0x55c73e8332b0)) and that the inner(after) calls at each level of outer recursion see the same $x variable (with value 0), namely the one from the innermost (outer(0)) level of recursion.
"Attempt 2" is the expected behavior (I don't know why it behaves differently when called a second time). Here every level of outer has a different inner sub, and inner at each level of recursion sees a different $x variable, both before and after the recursive call to outer.
This bug is reproducible in all perl versions I've tried: 5.39.6, 5.38.2, 5.38.0, 5.36.0, 5.34.1, 5.30.3, 5.26.1, 5.20.3.
(Thanks to vms14 from libera.chat #perl for finding this!)