Reputation: 75
I am having a hard time wrapping my head around this little snippet of code:
my $ref = \@{$seq->{$label}{$ARGV[4]}};
Can I get some help deciphering this?
Upvotes: 4
Views: 95
Reputation: 52102
$seq
is a hash reference$seq->{$label}
returns the value of the $label
key in the dereferenced hash$ARGV[4]
key
@ARGV
is the array of command line arguments, $ARGV[4]
is the element at index 4@{...}
Summary: it's the reference to the array that is the value of the $ARGV[4]
key in the hash returned by $seq->{$label}
, and the whole thing could IMHO be written
my $ref = $seq->{$label}{$ARGV[4]};
See Borodin's answer for the difference between \@{$ref}
and $ref
.
Upvotes: 3
Reputation: 42095
my $ref = \@{$seq->{$label}{$ARGV[4]}};
It's best to work from inside out for order of operation:
$ARGV[4]
: the fifth argument passed in through the command line (e.g., ./perlscript.pl "argument1" "argument2" "argument3" "argument4" "argument5.txt"
)$seq->{ $label }{ $ARGV[4]}
: this is holding a ref to an array, we know this because when you try to dereference it by wrapping it in @{ ... }
, you would otherwise receive a warning saying Not an ARRAY reference. Also, in place of variables you could also use bare strings (e.g., $seq->{ 'some label' }{ 'some other label'}
)@{ $seq->{ $label }{ $ARGV[4] } }
: this is doing the dereferencing, as mentioned in #3\@{ $seq->{ $label }{ $ARGV[4] } }
: the slash is making it a reference again, clarifying that an array reference was being held in the hashmy $ref = \@{ $seq->{ $label }{ $ARGV[4] } };
: your standard variable assignmentWe haven't seen much other code, so it's tough to say how much this may need updated. Usually you would want to sanitize your inputs, to make sure no bad or extremely large data is being passed in. Additionally, you would want to make it more meaningful. $seq
could be sequence or anything really, $label
is not too identifiable, and using any $ARGV
as you have done, generally means something else is not being done elsewhere.
Upvotes: 1
Reputation: 126722
Lets rewrite it like this
my $ref = \@{
$seq->{ $label }{ $ARGV[4] }
}
The outer my $ref =
is an assignment. I presume that's clear
Then @{ ... }
dereferences the contents of the braces as an array, and \
then takes a reference to that. The reference cancels out the dereference, so it's identical to
my $ref = $seq->{ $label }{ $ARGV[4] }
except that the dereference will cause the program to die with
Not an ARRAY reference
if the contents aren't a reference to an array
Now we have
$seq->{ $label }{ $ARGV[4] }
which uses $seq
as a reference to a hash of hashes, and uses $label
as the first-level key and $ARGV[4]
(the fifth command-line argument) as the second-level key
That statement was written by someone who I will generously call a poor programmer. I doubt if it was intended to check for the hash value being an array reference, and at the very least $ARGV[4]
should be copied to a named variable to make the meaning clear
Upvotes: 6