Reputation: 973
Is there anyway to do something like this in perl (convert array hash and use it in one line)?
sub func{
#from this
my %args = @_;
print $args{test};
#to this
print %{@_}{test};
}
Im using it for passing errors to callbacks like javascript use strict; use warnings;
sub error{
my $msg = shift;
print("ERROR: $msg\n");
}
sub parse_args{
my %args = @_;
return $args{args};
}
sub do_something{
my $args = parse_args(
args=>{@_},
optional_args=>["fail_cb"]
);
if(!0){
return(exists $args->{fail_cb} ? $args->{fail_cb}->(err=>"not good") : 0);
}
}
do_something(
fail_cb => sub{error(({@_})->{err});}
);
Upvotes: 1
Views: 131
Reputation: 66883
Yes, by making it into a reference and then dereferencing
sub func { say ${{@_}}{key} }
(I must ask, do you really want to be doing this?)
The {@_}
creates a hash reference, while ${ ... }{}
syntax dereferences it (item 2).
Update to the question edit
Apparently, the intent is to run a callback. But then you need to run that callback
sub func { ${{@_}}{key}->() }
func( key => sub { say "cb here" } );
If you were to print the value, as asked, you'd get the code-reference itself, CODE(0x...)
Or, pass the hashref with a key and (the reference of) arguments for the callback
my $hr = { k1 => sub { .. }, k2 => sub { .. }, .. };
...
func($hr, $key, $arrayref_cb_args);
sub func { $_[0]->{$_[1]}->(@{$_[2]}) }
where now func
can decide dynamically what to run. This gives you far more flexibility in design.
For a ready test
perl -wE'
sub tt { $_[0]->{$_[1]}->(@{$_[2]}) };
tt( { k1 => sub { say "args: @_" }}, "k1", [qw(cb here)] )
'
prints the line args: cb here
Upvotes: 2
Reputation: 86774
You can turn it into a hash reference easily with just
{@a}
and dereference entries with, for example
({@a})->{key}
Here's a debugger log:
$ perl -de0
Loading DB routines from perl5db.pl version 1.49_001
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(-e:1): 0
DB<1> @a = ('a',1,'b',2,'c',3)
DB<2> x @a
0 'a'
1 1
2 'b'
3 2
4 'c'
5 3
DB<3> x {@a}
0 'a'
1 1
2 'b'
3 2
4 'c'
5 3
DB<4> x ({@a})
0 HASH(0x804d82e0)
'a' => 1
'b' => 2
'c' => 3
DB<5> x ({@a})->{c}
0 3
Upvotes: 1