4

I've got a hash with let's say 20 values.

It's initialized this way:

my $line = $_[0]->[0];

    foreach my $value ($line) {
        print $value;
    }

Now when I try to get the value of each hash in $line it says: Use of uninitialized value in print at file.pl line 89

Is there a way to iterate through each value of a hash?

I also tried it with:

my %line = $_[0]->[0];

    foreach my $key (keys %line) {
        print %line->{$key};
    }

But that is also not working: Reference found where even-sized list expected at file.pl at line 89

Anybody knows what to do? It shouldn't be that difficult...

Adam Crossland
  • 14,198
  • 3
  • 44
  • 54
baklap
  • 2,145
  • 6
  • 28
  • 41

4 Answers4

12

To iterate over values in a hash:

for my $value (values %hash) {
  print $value;
}
Grey Panther
  • 12,870
  • 6
  • 46
  • 64
3

$line in your first example is a scalar, not a hash.

If it's a hash reference, dereference it with %{$line}.

Christoffer Hammarström
  • 27,242
  • 4
  • 49
  • 58
  • 1
    Ah I see! Now it's working with: my $line = $_[0]->[0]; foreach my $value (values %{$line}) { print $value . "\n"; } – baklap Nov 10 '10 at 14:51
3

First, you must understand the difference between a hash, and a hash reference.

Your initial assignment $_[0]->[0] means something like : Takes the first argument of the current function ($_[0]), dereference it (->) and consider it is an array and retrieves it's first value ([0]). That value can not be a list or a hash, it must be a scalar (string, int, float, reference).

Here is some example:

my %hash = ( MyKey => "MyValue");
my $hashref = \%hash;
# The next line print all elements of %hash
foreach (keys %hash) { print $_ }
# And is equivalent to
foreach (keys %{$hashref}) { print $_ }
$hash{MyKey} == $hashref->{MyKey}; # is true

Please refer to http://perldoc.perl.org/perlreftut.html for further details.

OMG_peanuts
  • 1,797
  • 1
  • 13
  • 19
  • No, `$_[0]` is not a function. It’s the first (scalar) element of `@_`. So `$_[0]->[0]` — which is the same as `$_[0][0]` and `${ $_[0] }[0]` — takes that first scalar element of `@_`, construes it to be a reference to an array, and returns the first element of that putatively referenced array. – tchrist Nov 10 '10 at 15:06
  • Never said that $_[0] was a function. – OMG_peanuts Nov 10 '10 at 15:19
2

The warning is telling you that there nothing at $_[0]->[0]. It's not dying and telling you that you're indexing nothing, so $_[0] is likely an arrayref, but nothing is in the first slot--or perhaps it's pointing to an empty array.

  • Were it a empty string or a 0, it wouldn't complain.
  • Were there any reference there, you could print something even if only: BLAH(0x80af74). (Where "BLAH" is one of "ARRAY", "HASH", "SCALAR", "REF", "GLOB", "IO", ... )

My suggestion is that you do this:

use Data::Dumper;
say Data::Dumper->Dump( [ $_[0] ] ); # or even say Data::Dumper->Dump( [ \@_ ] )

and then look at the output.

Once you've got a hashref at $_[0]->[0], then if you must loop through the hash, the best way is:

while ( my ( $key, $value ) = each %$hashref ) { 
   do_stuff_with_key_and_value( $key, $value );
}

see each

Lastly, it seems that you have some sigil confusion. See the last part of this link for a decent attempt to explain that sigils ( '$', '@', '%' ) are not part of the name of a variable, but indicators what we want retrieved from it. Perl compilation woes

Community
  • 1
  • 1
Axeman
  • 29,660
  • 2
  • 47
  • 102