Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > could you use array or string as hash key in Perl?

Reply
Thread Tools

could you use array or string as hash key in Perl?

 
 
Summercool
Guest
Posts: n/a
 
      09-19-2007
could you use array or string as hash key in Perl?

and then what if you modify the array or string internally?

i tried

@a = (3,4);

$h{@a} = "ha";

and it took @a as the number 2.

 
Reply With Quote
 
 
 
 
Paul Lalli
Guest
Posts: n/a
 
      09-19-2007
On Sep 19, 8:50 am, Summercool <(E-Mail Removed)> wrote:
> could you use array or string as hash key in Perl?


Array, no. String, yes.

Keys are scalars. If you try to use a non-scalar as a key, that non-
scalar is evaluated in scalar context.

> and then what if you modify the array or string internally?
>
> i tried
>
> @a = (3,4);
>
> $h{@a} = "ha";
>
> and it took @a as the number 2.


Right. Because an array in scalar context returns its size. The size
of @a is 2.

I suppose you could use the stringified version of a reference to the
array as the key:
$h{\@a} = "ha";
but I have no idea why you would want to do such a thing.

What are you *trying* to do? What is your end goal?

If you're trying to make a multidimensional structure, you should read
up on references:
perldoc perlreftut
perldoc perllol
perldoc perldsc

Paul Lalli

 
Reply With Quote
 
 
 
 
Ben Bullock
Guest
Posts: n/a
 
      09-19-2007
On Wed, 19 Sep 2007 12:50:10 +0000, Summercool wrote:

> could you use array or string as hash key in Perl?
>
> and then what if you modify the array or string internally?
>
> i tried
>
> @a = (3,4);
>
> $h{@a} = "ha";
>
> and it took @a as the number 2.


That is the answer to your question, in fact. Perl doesn't like your array
in its hash argument, so it decides to change your array into a scalar. The
number 2 is the "scalar value" of your array, which is the number of
elements in the array.

Thus Perl has already told you that you can't use an array as a hash key.

Of course you can use a string as a hash reference. To find out what Perl
does if you change the value of the string, write a simple test, run it
and see what happens.

#!/usr/bin/perl
use warnings; use strict;
my $string = "frog";
my %animals;
$animals{$string} = "amphibian";
$string = "dolphin";
print $animals{$string}, "\n";
print $animals{frog}, "\n";
 
Reply With Quote
 
Michele Dondi
Guest
Posts: n/a
 
      09-19-2007
On Wed, 19 Sep 2007 12:50:10 -0000, Summercool
<(E-Mail Removed)> wrote:

>could you use array or string as hash key in Perl?


A hash key in current Perl can *only* be a string.

If you want to use an array you have to specify your own array to
string conversion facility in a way that is suitable for the problem
at hand. A simple "@array" may be appropriate or totally wrong,
depending on the actual situation.

>and then what if you modify the array or string internally?


"Internally" as opposed to... what?

>i tried
>
>@a = (3,4);
>
>$h{@a} = "ha";
>
>and it took @a as the number 2.


Of course, because the array is evaluated in a scalar context and in a
scalar context an array is its size.

You may want to use the reference to the array, in which case the key
will stay the same also if you modify the array later. You just have
to know that the key will *not* be the reference, but also in this
case, its stringification: i.e. do not hope to recover the array
directly from the key, although that is not what you were asking for.
Incidentally, if you want to, then there's a suitable module to do
exactly that.


cognac:~ [16:06:18]$ perl -MData:umper -e '@a=3..4; print Dumper \
{ "@a" =>1, \@a => 2 }'
$VAR1 = \{
'ARRAY(0x814fe34)' => 2,
'3 4' => 1
};
cognac:~ [16:06:25]$ perl -le '@a=3..4; $h{"@a"}=3; push @a,1; \
print $h{"@a"} || "undef"'
undef
cognac:~ [16:06:33]$ perl -le '@a=3..4; $h{\@a}=3; push @a,1; \
print $h{\@a} || "undef"'
3


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
 
Reply With Quote
 
Michele Dondi
Guest
Posts: n/a
 
      09-19-2007
On Wed, 19 Sep 2007 14:06:52 +0000 (UTC), Ben Bullock
<(E-Mail Removed)> wrote:

>That is the answer to your question, in fact. Perl doesn't like your array
>in its hash argument, so it decides to change your array into a scalar. The
>number 2 is the "scalar value" of your array, which is the number of
>elements in the array.
>
>Thus Perl has already told you that you can't use an array as a hash key.


This is misleading: using a bare array as hash key is perfectly valid
syntax with an acceptable semantics. So you *can* "use an array as a
hash key": it simply won't do what the OP wanted, whatever it was.


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
 
Reply With Quote
 
Ben Bullock
Guest
Posts: n/a
 
      09-19-2007
On Wed, 19 Sep 2007 16:49:10 +0200, Michele Dondi wrote:

> On Wed, 19 Sep 2007 14:06:52 +0000 (UTC), Ben Bullock
> <(E-Mail Removed)> wrote:
>
>>That is the answer to your question, in fact. Perl doesn't like your
>>array in its hash argument, so it decides to change your array into a
>>scalar. The number 2 is the "scalar value" of your array, which is the
>>number of elements in the array.
>>
>>Thus Perl has already told you that you can't use an array as a hash
>>key.

>
> This is misleading: using a bare array as hash key is perfectly valid
> syntax with an acceptable semantics. So you *can* "use an array as a
> hash key": it simply won't do what the OP wanted, whatever it was.


In the original poster's post he says

> i tried
> @a = (3,4);
> $h{@a} = "ha";
> and it took @a as the number 2.


so he clearly already knows that using an array as a hash key isn't a
syntax error.
 
Reply With Quote
 
patrick
Guest
Posts: n/a
 
      09-19-2007
On Sep 19, 5:50 am, Summercool <(E-Mail Removed)> wrote:
> could you use array or string as hash key in Perl?
>
> and then what if you modify the array or string internally?
>
> i tried
>
> @a = (3,4);
>
> $h{@a} = "ha";
>
> and it took @a as the number 2.


If you want to try and keep the array values you can always use

$h{ join('.', @a) } = 'ha';

print " $h{ join('.', @a) }\n";

====>Patrick

 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      09-19-2007

Quoth Paul Lalli <(E-Mail Removed)>:
> On Sep 19, 8:50 am, Summercool <(E-Mail Removed)> wrote:
> > could you use array or string as hash key in Perl?

>
> Array, no. String, yes.
>
> Keys are scalars.


No, keys are strings (except in tied hashes). This is important, as it
is why using a ref as a key doesn't work.

> If you try to use a non-scalar as a key, that non- scalar is evaluated
> in scalar context.


....and then stringified.

Ben

 
Reply With Quote
 
Summercool
Guest
Posts: n/a
 
      09-19-2007
yes, i tried using

$h{(3,4)} = "hee";

and print out all the key value pairs.
the key "3 4" show up with a strange character between them.


 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      09-19-2007

Quoth Summercool <(E-Mail Removed)>:
> yes, i tried using
>
> $h{(3,4)} = "hee";
>
> and print out all the key value pairs.
> the key "3 4" show up with a strange character between them.


That character is the value of $; (by default "\034"), and is how Perl 4
used to do multi-level hashes before Perl 5 and refs were invented.
Using a (literal) list as a key is well worth avoiding nowadays.

Ben

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
hash of hash of hash of hash in c++ rp C++ 1 11-10-2011 04:45 PM
Hash#select returns an array but Hash#reject returns a hash... Srijayanth Sridhar Ruby 19 07-02-2008 12:49 PM
Benchmark segfault [Was: Array#inject to create a hash versus Hash[*array.collect{}.flatten] ] Michal Suchanek Ruby 6 06-13-2007 04:40 AM
Array#inject to create a hash versus Hash[*array.collect{}.flatten] -- Speed, segfault Anthony Martinez Ruby 4 06-11-2007 08:16 AM
hash key to var name of value hash key value Une bévue Ruby 5 08-10-2006 04:05 PM



Advertisments