Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > error when accessing hash of arrays

Reply
Thread Tools

error when accessing hash of arrays

 
 
Harald
Guest
Posts: n/a
 
      03-14-2006
HI!

I am a perl newbie and have a problem which can be reduced to the following:

I have a hash-reference of a hash, which values are references to
arrays. Now I want to know the length of the first value. I try it with:

use strict;

my $hash = {"A"=>[1,2,3,4], "B"=>[5,6,7,8]};
my $length = $#{values(%{$hash})[0]};
print $length;

But if I run it, perl says:
##############
Global symbol "$length" requires explicit package name at t.pl line 5.
Execution of t.pl aborted due to compilation errors.
##############
what is absolutely strange to me.
If I comment out line 5 (which is "print ..."), I receive the error:
###############
syntax error at t.pl line 4, near ")["
Execution of t.pl aborted due to compilation errors.
###############
Which is nearly as strange to me than the first error-message.

As far as I understand, $hash is dereferenced by %{$hash}.
Then I get a list of all its values by values( %{$hash} ).
Then I get its first value by values( %{$hash} )[0].
Then I dereference it and get its size minus 1 by $#{values(%{$hash})[0]}

Could anyone tell me where my mistake is?

Regards and thanks in advance,
Harald
 
Reply With Quote
 
 
 
 
A. Sinan Unur
Guest
Posts: n/a
 
      03-14-2006
Harald <(E-Mail Removed)> wrote in news:dv6hmr$5m1$02$(E-Mail Removed)-online.com:

> I have a hash-reference of a hash, which values are references to
> arrays. Now I want to know the length of the first value. I try it
> with:
>
> use strict;
>
> my $hash = {"A"=>[1,2,3,4], "B"=>[5,6,7,8]};
> my $length = $#{values(%{$hash})[0]};
> print $length;


If that worked, it would have given you the index of the last element,
not the length of the array.

Second, there is no "first" element of a hash. By its very nature, a
hash table is unordered (unless you are using Tie::IxHash).

Let's see:

$hash->{A}

is a reference to an array.

@[ $hash->{A} ]

dereferences it.

my $length = @[ $hash->{A} ];

Assigns the length of the array to $length.

Alternatively:

#!/usr/bin/perl

use strict;
use warnings;

my $hash = { A =>[1,2,3,4], B => [5,6,7,8] };

for my $v ( values %{ $hash } ) {
print scalar @$v, "\n";
}
__END__

--
A. Sinan Unur <(E-Mail Removed)>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html

 
Reply With Quote
 
 
 
 
Paul Lalli
Guest
Posts: n/a
 
      03-14-2006
Harald wrote:
> I am a perl newbie and have a problem which can be reduced to the following:
>
> I have a hash-reference of a hash, which values are references to
> arrays. Now I want to know the length of the first value. I try it with:


Careful with your terminology. "length" generally refers to the number
of characters in a string. (See: perldoc -f length). You're looking
for the *size* of an array.

> use strict;
>
> my $hash = {"A"=>[1,2,3,4], "B"=>[5,6,7,8]};
> my $length = $#{values(%{$hash})[0]};
> print $length;
>
> But if I run it, perl says:
> ##############
> Global symbol "$length" requires explicit package name at t.pl line 5.
> Execution of t.pl aborted due to compilation errors.
> ##############
> what is absolutely strange to me.


That's perl-speak for "I couldn't compile this line, so $length was
never declared". At least, that's how I interpret it.

> If I comment out line 5 (which is "print ..."), I receive the error:
> ###############
> syntax error at t.pl line 4, near ")["
> Execution of t.pl aborted due to compilation errors.
> ###############
> Which is nearly as strange to me than the first error-message.


And yet, it's completely accurate.

> As far as I understand, $hash is dereferenced by %{$hash}.


yes.

> Then I get a list of all its values by values( %{$hash} ).


yes.

> Then I get its first value by values( %{$hash} )[0].


no!

the [0] is attempting to be applied to the (%{$hash}), not to the list
returned by values(). You're getting bitten by precedence.

(values ( %{$hash} ) )[0]

> Then I dereference it and get its size minus 1 by $#{values(%{$hash})[0]}


$#{ (values (%{$hash}) )[0] }

> Could anyone tell me where my mistake is?


Your actual mistake I've already addressed. Your first mistake,
however, is trying to do this all in one line, IMO.

my @values = values %{$hash};
my $size_of_first = @{ $values[0] };

Does it take longer to write? Yes. But it's also a lot easier to
understand.

Paul Lalli

 
Reply With Quote
 
xhoster@gmail.com
Guest
Posts: n/a
 
      03-14-2006
Harald <(E-Mail Removed)> wrote:
> HI!
>
> I am a perl newbie and have a problem which can be reduced to the
> following:
>
> I have a hash-reference of a hash, which values are references to
> arrays. Now I want to know the length of the first value. I try it with:


Generally, hashes have no "first" value. Do you want the length of (the
array referenced by) an arbitrary entry?


>
> use strict;
>
> my $hash = {"A"=>[1,2,3,4], "B"=>[5,6,7,8]};
> my $length = $#{values(%{$hash})[0]};
> print $length;


Thank you for using strict, and for posting complete, runnable (well,
runnable other than the very syntax error which you were asking about)
code.

[0] is used to index into either an array or a list. But to index into
a list, the list must be paranthesized. In this case, your intended list
is not parenthesized. Move the '(' from just after to just before the
"values".

my $length = $#{(values %{$hash})[0]};

Now the list returned by values is a paranthesized and hence indexable
list, and it will work. (But it isn't the length, it is the index of the
last element, i.e. the length minus one.)


>
> But if I run it, perl says:
> ##############
> Global symbol "$length" requires explicit package name at t.pl line 5.
> Execution of t.pl aborted due to compilation errors.
> ##############


In my perl, I get the below syntax error first, then the above "requires
explicit package" on the next line. Are you sure that isn't the case for
you as well, and perhaps you are missing the first error statment?

Anyway, perl doesn't just stop at the first syntax error it sees. It tries
to go on to critique the rest of your code as well. But to do so, it has
to somehow recover from the syntax error. That recovery is rarely perfect,
and here one result of it is that it fails to record the "my"ing of
$length.

Generally, any errors or warnings reported after the occurence of a syntax
error are dubious.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
 
Reply With Quote
 
Harald
Guest
Posts: n/a
 
      03-14-2006
Hello,

thanks for your reply.
In my problem all the arrays that are hashed are of the same length so I
am just interested in one arrays size. No matter which. So I will stick
with the solution of the other posters.

Thanks a lot for your reply and your comments. Perl becomes more and
more clearer.

but this does not work with my perl:

>
> my $length = @[ $hash->{A} ];
>


It works only with
my $length = @{ $hash->{A} };

Regards,
Harald
 
Reply With Quote
 
Harald
Guest
Posts: n/a
 
      03-14-2006
Hello.

Thanks a lot. I had tried it with brackets to inforce the right operator
precedence but it lead to errors because I tried to do it all in one line.

But you are right. Breaking it up into two lines is much more readable!

Regards,
Harald
 
Reply With Quote
 
Harald
Guest
Posts: n/a
 
      03-14-2006
Hello.

Thanks a lot.
As far as I imagine I had tried it with different ways of ('s and )'s
but it did not work

And no, the error message was produces just as I have printed it in my
first mail.

Regards,
Harald
 
Reply With Quote
 
A. Sinan Unur
Guest
Posts: n/a
 
      03-14-2006
Harald <(E-Mail Removed)> wrote in news:dv6p0h$ggb$00$(E-Mail Removed)-online.com:

> but this does not work with my perl:
>
>>
>> my $length = @[ $hash->{A} ];
>>

>
> It works only with
> my $length = @{ $hash->{A} };


Of course, I was typing too fast for my own good. Thanks for catching
that.

Sinan
--
A. Sinan Unur <(E-Mail Removed)>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html

 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      03-14-2006
Harald <(E-Mail Removed)> wrote:

> the error message was produces just as I have printed it in my
> first mail.



This is not email.

This is a Usenet newsgroup.

The difference matters.


--
Tad McClellan SGML consulting
http://www.velocityreviews.com/forums/(E-Mail Removed) Perl programming
Fort Worth, Texas
 
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 of Hash of Arrays Question Älphä Blüë Ruby 5 07-18-2009 07:36 PM
Multidimensional arrays and arrays of arrays Philipp Java 21 01-20-2009 08:33 AM
hash of arrays - appending to one of the arrays Adam Akhtar Ruby 5 03-25-2008 11:53 PM
Accessing Hash of hash of arrays Lynn Perl Misc 9 02-16-2005 06:59 PM



Advertisments