So I wrapped up the previously mentioned named parameter binding code into a module called Params::Named which should now be available on the CPAN. It's now more robust and deals with arrays and hashes to boot. Go crazy.
Re:Cool
broquaint on 2005-10-12T10:00:34
But you're right that this isn't very robust. (If the sub has other lexical variables with the same names, you could get the wrong one. And some improvements in the latest beta actually make it *more* likely that you'd get the wrong one, sad to say.)
Thankfully it is a little more robust than that - instead of assigning to the hash returned by PadWalker that hash is used as a reference to map parameters (i.e the lexicals passed to MAPARGS) to the named arguments. Simply assigning to the returned hash could, as you say, "get the wrong one". Feel free to look at the code to see the magic at work, although it is a little, er, twisty:) Re:Cool
robin on 2005-10-12T15:31:48
I did look at the code, and I grok what it's doing (which is very cool). What I mean is that:
use Params::Named;
sub ick {
MAPARGS \my($foo, $bar);
print "Foo = $foo\n";
{my $foo}
}
ick(foo => 23)will give the spurious error
The parameter '$foo' doesn't match argument type 'SCALAR'
.The problem, of course, is that sub ick has more than one lexical called 'foo', and in this case peek_sub is returning the wrong one, so you don't find the correct
$foo
at all.What you really need is a kind of reverse peek, where you can ask "what's the name of this variable?".
Re:Cool
broquaint on 2005-10-13T09:17:30
Ack! You're quite right:/ How about a patch to PadWalker which adds another magical sub that returns a more detailed data structure than a flat hash, or some such? My XS is non-existant but how hard can it be, right? A reverse peek would be handy but my limited knowledge of perl's internals leads me to believe it'd involve something genuinely mad like adding debugging info to the optree. Which would be nice :) Re:Cool
robin on 2005-10-13T13:48:46
Check out the latest PadWalker beta, which has a new function called
var_name
.Using that, you should also be able to make your module work from anonymous subs (which I assume it doesn't, at the moment).