Reputation: 587
I have one hash there I have two key, I want to use one key as a value of another key. Is it possible in Perl?
exp:
%hash= (
abs =>[a,b,c,e];
xyz=> abs
);
I tried but was not able to do this.
Upvotes: 2
Views: 527
Reputation: 67900
You can use whatever value you wish as a hash value, including the name of another key. You can not, however, fail to quote the value, as it is not automagically quoted like the keys:
my %hash = (
abs => 'foo',
xyz => 'abs'
);
Quoting a parameter preceeding =>
is optional, if it does not contain spaces. Quoting the parameter following it is not.
You might also be interested to know that
[a,b,c,d]
will produce warnings, if you have warnings turned on (which you always should).
Unquoted string "a" may clash with future reserved word at
Unquoted string "b" may clash with future reserved word at
The reason this still "works" is -- as far as I know -- for backwards compatibility, and you should always quote your strings. Furthermore, case in point, your bareword abs
is actually mistaken for the built-in function abs
, which in this case will try to find the absolute value of $_
, and probably fail, returning 0 (and issuing a warning about undefined value in $_
).
What your array ref should look like is this:
['a', 'b', 'c', 'd']
Or with a simpler syntax, using the qw()
operator:
[ qw(a b c d) ]
You might also note that semi-colon ;
is not a valid character inside an assignment to a hash. The key/value pairs inside the parentheses shall be delimited with commas, nothing else.
Upvotes: 2
Reputation: 530853
One problem is that while the hash is being defined, it is anonymous. Not until the entire list is parsed is it assigned to %hash
, so there's really no way to reference earlier parts of the hash while it is being defined. There are a couple of workarounds available:
my $common_lref = ['a', 'b', 'c', 'e'];
my %hash = ( abs => $common_lref, xyz => $common_lref );
or
my %hash = ( abs => ['a', 'b', 'c', 'e'] );
$hash{xyz} = $hash{abs};
In both cases, changing the array referenced by $hash{abs}
changes $hash{xyz}
, and vice versa.
Note: This only works if the value is a reference (as it is here), and only it only works as long as you don't change $hash{abs}
or $hash{xyz}
. You can still change the elements of the array referenced by $hash{abs}
and $hash{xyz}
(including adding and deleting elements).
Upvotes: 1
Reputation: 4088
This code doesn't compile.
Here's a working example:
#!/usr/bin/perl
use strict;
use warnings;
my %hash = (
abs => ['a', 'b','c','e'],
xyz=> 'abs'
);
print "abs: @{ $hash{$hash{xyz}} }\n";
First, use use warnings; use strict;
You have to quote your value at xyz =>
. Side note: abs
is also a perl built-in.
You also need to quote your anonymous array value at abs =>
:
Eg, `[ qw(a b c) ]` or `['a', 'b', 'c',]`.
Then in the print, I dereference(@{}
) the value, as it is a list
.
Upvotes: 0
Reputation: 3498
First, always use
use strict;
use warnings;
then, this should work:
my %hash = (
abs => [ qw(a b c) ],
xyz => 'abs',
);
print $hash{ $hash{xyz} }[0];
# prints 'a'
Upvotes: 1
Reputation: 701
You are simply using a wrong syntax. Try this instead:
#!/usr/bin/env perl
# warnings and strict are ALWAYS a good idea in perl code
use warnings;
use strict;
my %hash = (
abs => ['a', 'b','c','e'], # make strings clear and use a comma, no semicolon
xyz => 'abs'
);
And if you want your hash printed out, just to check it, Data::Dumper
is useful - especially once you have a bigger hash:
use Data::Dumper;
print Dumper(\%hash);
Upvotes: 2