I'm sending a subroutine a hash, and fetching it with my($arg_ref) = @_;
But what exactly is %$arg_ref
? Is %$
dereferencing the hash?
I'm sending a subroutine a hash, and fetching it with my($arg_ref) = @_;
But what exactly is %$arg_ref
? Is %$
dereferencing the hash?
$arg_ref
is a scalar since it uses the $
sigil. Presumably, it holds a hash reference. So yes, %$arg_ref
deferences that hash reference. Another way to write it is %{$arg_ref}
. This makes the intent of the code a bit more clear, though more verbose.
To quote from perldata(1)
:
Scalar values are always named with '$', even when referring
to a scalar that is part of an array or a hash. The '$'
symbol works semantically like the English word "the" in
that it indicates a single value is expected.
$days # the simple scalar value "days"
$days[28] # the 29th element of array @days
$days{'Feb'} # the 'Feb' value from hash %days
$#days # the last index of array @days
So your example would be:
%$arg_ref # hash dereferenced from the value "arg_ref"
my($arg_ref) = @_;
grabs the first item in the function's argument stack and places it in a local variable called $arg_ref
. The caller is responsible for passing a hash reference. A more canonical way to write that is:
my $arg_ref = shift;
To create a hash reference you could start with a hash:
some_sub(\%hash);
Or you can create it with an anonymous hash reference:
some_sub({pi => 3.14, C => 4}); # Pi is a gross approximation.
Instead of dereferencing the entire hash like that, you can grab individual items with
$arg_ref->{key}
A good brief introduction to references (creating them and using them) in Perl is perldoc perfeftut
. You can also read it online (or get it as a pdf). (It talks more about references in complex data structures than in terms of passing in and out of subroutines, but the syntax is the same.)
Since it's somewhat clear this construct is being used to provide a hash reference as a list of named arguments to a sub it should also be noted that this
sub foo {
my ($arg_ref) = @_;
# do something with $arg_ref->{keys}
}
may be overkill as opposed to just unpacking @_
sub bar {
my ($a, $b, $c) = @_;
return $c / ( $a * $b );
}
Depending on how complex the argument list is.
my %hash = ( fred => 'wilma',
barney => 'betty');
my $hashref = \%hash;
my $freds_wife = $hashref->{fred};
my %hash_copy = %$hash # or %{$hash} as noted above.
Soo, what's the point of the syntax flexibility? Let's try this:
my %flintstones = ( fred => { wife => 'wilma',
kids => ['pebbles'],
pets => ['dino'],
}
barney => { # etc ... }
);
Actually for deep data structures like this it's often more convenient to start with a ref:
my $flintstones = { fred => { wife => 'Wilma',
kids => ['Pebbles'],
pets => ['Dino'],
},
};
OK, so fred gets a new pet, 'Velociraptor'
push @{$flintstones->{fred}->{pets}}, 'Velociraptor';
How many pets does Fred have?
scalar @ {flintstones->{fred}->{pets} }
Let's feed them ...
for my $pet ( @ {flintstones->{fred}->{pets} } ) {
feed($pet)
}
and so on. The curly-bracket soup can look a bit daunting at first, but it becomes quite easy to deal with them in the end, so long as you're consistent in the way that you deal with them.