Reputation: 39158
My function is
use 5.028;
use strictures;
use Kavorka qw(fun);
fun foobar(:$foo, :$bar) { say $foo, $bar; }
I need to pass it named arguments, not positional arguments.
foobar('quux', 'quuuux');
# Unknown named parameter: quux at … line 5.
# main::foobar("quux", "quuuux") called at … line 7
but
foobar(foo => 'quux', bar => 'quuuux');
# ok
Hash
es or HashRef
s are accepted, too.
my %args = (foo => 'quux', bar => 'quuuux');
foobar(%args);
my $args = {foo => 'quux', bar => 'quuuux'};
foobar($args);
In ES6 exists a short-cut where variables in an object literal are expanded (ed: MDN link?):
function foobar({foo, bar}) { console.log(foo, bar); }
foobar({foo: 'quux', bar: 'quuuux'});
const foo = 'quux';
const bar = 'quuuux';
foobar({foo: foo, bar: bar});
foobar({foo, bar}); // NB!
In Perl 6 a :
prefixed variable in a parameter signature will create a key of the same name:
use v6;
sub foobar(:$foo, :$bar) { say $foo, $bar; }
foobar(foo => 'quux', bar => 'quuuux');
my $foo = 'quux';
my $bar = 'quuuux';
foobar(foo => $foo, bar => $bar);
foobar(:$foo, :$bar); # NB!
How can you accomplish something comparable in effect for Perl 5?
my $foo = 'quux';
my $bar = 'quuuux';
foobar(???);
Upvotes: 4
Views: 229
Reputation: 666
I have a couple of ways of doing it, using either PadWalker (thanks for the suggestion mob) or Hash Slices:
use strict;
use warnings;
use Data::Dumper;
use PadWalker qw/ var_name /;
sub test_sub { print Dumper [ @_ ] }
my %vars;
$vars{foo} = "foo_data";
$vars{bar} = "var_data";
test_sub( %{vars}{qw/ foo bar/} );
# nv = named variables ( rename as needed )
sub nv { map { ( substr( var_name(1, \$_), 1) => $_ ) } @_ }
my $foo = 'foo_stuff';
my $bar = 'bar_stuff';
test_sub( nv( $foo, $bar ) );
Which gives:
$VAR1 = [
'foo',
'foo_data',
'bar',
'var_data'
];
$VAR1 = [
'foo',
'foo_stuff',
'bar',
'bar_stuff'
];
Had to do the substr in nv otherwise it shows the sigil, but thats about the best I can think of without going into deeper magic.
Without using nv, that will require more deep magic manipulation...
Using your Kavorka code as well:
use 5.020;
use strictures;
use Kavorka qw(fun);
use PadWalker qw/ var_name /;
fun foobar(:$foo, :$bar) { say $foo, $bar; }
my %vars;
$vars{foo} = "foo_data";
$vars{bar} = "var_data";
foobar( %{vars}{qw/ foo bar/} );
# nv = named variables ( rename as needed )
sub nv { map { ( substr( var_name(1, \$_), 1) => $_ ) } @_ }
my $foo = 'foo_stuff';
my $bar = 'bar_stuff';
foobar( nv( $foo, $bar ) );
gives:
foo_datavar_data
foo_stuffbar_stuff
I dont have 5.28 installed locally unfortunately heh
Upvotes: 4