in reply to Re^2: Silencing specific warnings when executing coderef?
in thread Silencing specific warnings when executing coderef?
"Will you come to Sofia?"
If someone pays me to, sure.
"Dunno if caller is somehow safely overwritable"
It can, Sub::Uplevel does this (and documents the caveats).
"Did you notice that Jesse Luehr's module (thanks for showing, BTW) explicitly warns about using it?"
It was my bug report that led him to add the warning. The issue can be worked around with PadWalker though, and that's what I do in the section of my example commented Fix Parse::Keyword's handling of closed over variables. I use Parse::Keyword in a few projects, and with a bit of care, PadWalker seems to be able to fix this problem every time.
The basic problem can be illustrated with this code sample:
use v5.14; my (@x, @y); for my $i (1..3) { push @x, sub { 1 }; push @y, sub { $i }; } say @x; say @y;
It will produce output something like this:
CODE(0x9c3cce8)CODE(0x9c3cce8)CODE(0x9c3cce8) CODE(0x9c2b228)CODE(0x9c2bd08)CODE(0x9c3c9d8)
You'll notice that @x has the same reference three times, while @y has three different references. This is because at compile-time, when a coderef is encountered, and Perl notices that it closes over a variable, it compiles it into a sort of "proto-coderef". Then when the coderef is hit at run-time (in the example above, the execution of the for loop), Perl sees that it's got a proto-coderef, and fixes up the closed over variables to point to the right data. If the coderef doesn't close over any variables, then it can take the shortcut of reusing the same coderef each time it's encountered at run-time.
Anyway, the parse_* functions in Parse::Keyword essentially only give you a proto-coderef. If this closes over any lexical variables, you need to do the run-time "point to the right data" bit yourself. So that's what I do in the example.
If you comment out the PadWalker lines, you'll get warnings about the variables in $x..$y being undefined, this is because without PadWalker the list generation coderef $list is just a proto-coderef compiled before $x and $y have been given any values.
Anyway, I'm probably boring everybody now. I've just used Parse::Keyword more than most people. Despite its shortcomings, I still think there's life in it.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: Silencing specific warnings when executing coderef?
by LanX (Saint) on Mar 23, 2014 at 22:18 UTC | |
by tobyink (Canon) on Mar 24, 2014 at 10:42 UTC |