3

I have a question with the following Code:

#!/usr/bin/perl

use strict;
use warnings;

my %dmax=("dad" => "aaa","asd" => "bbb");
my %dmin=("dad" => "ccc","asd" => "ddd");

&foreach_schleife(\%dmax,\%dmin);

sub foreach_schleife {
        my $concat;
        my $i=0;

        foreach my $keys (sort keys %{$_[0]}) {
                while ($_[$i]) {
                        $concat.="$_[$i]{$keys} ";
                        print $_[$i]{$keys}."\n";
                        $i++;
                }
                $i=0;
                $concat="";
        }
}

The Output is:

   bbb
   ddd
   aaa
   ccc

I don't understand this. Normally you must dereference references on hashes,arrays etc. Why not here? Its enough to write :

$_[$i]{$keys}."\n";

and not something like that:

$$_[$i]{$keys}."\n";

Why? Has it something to do with the speciality of the variable @_/$_?

Hakan Kiyar
  • 1,199
  • 6
  • 16
  • 26
  • if you're satisfied with an answer, please [accept](http://stackoverflow.com/faq#reputation) it by pressing on the hollow green check mark next to it. It gives reputation to both you and the person whose answer you accepted, and is generally a good gesture. – Phonon Mar 01 '12 at 22:21

3 Answers3

3

My guess is that because an array (or a hash, for that matter) can only contain hash references your second act of indexing means that the reference is understood.

I think the developers need to document this a little better.

To see that it is not special to *_, you can try this before the loop:

my @a = @_;

And this during:

print $a[$i]{$keys}."\n";

I think the main thing is that if you only have a scalar reference as the base, then at least one -> is required. So

my ( $damxr, $dminr ) = @_;

would require

$dmaxr->{ $key };
Axeman
  • 29,660
  • 2
  • 47
  • 102
  • +1. In my opinion that short-hand notation is only useful for golfing, since it doesn't make sense even to seasoned Perl developers. – flesk Dec 12 '11 at 14:21
  • @flesk, you're entitled to your opinion. I think having a lot of `->` is excessive noise, if all you want to do is index. – Axeman Dec 12 '11 at 16:42
3

The reason why you don't have to dereference $_[0] and $_[1] is that $_[$i]{$keys} is a valid short-hand notation for $_[$i]->{$keys} when your reference is in an array or a hash.

$$_[$i]{$keys} won't work, because it will try to dereference the special variable $_ to a scalar. The correct syntax is %{$_[$i]}, but then you'll have to use %{$_[$i]}->{$keys}, which is more verbose.

flesk
  • 7,439
  • 4
  • 24
  • 33
0

@_ is the array of subroutine arguments, hence $_[$index] accesses the element at $index

Dereferencing is only good if you have references, but @_ isn't one.

Ingo
  • 36,037
  • 5
  • 53
  • 100
  • Ok @_ is no reference but its elements are.But i think the second reply to my posting give the probable right answer. – Hakan Kiyar Dec 12 '11 at 13:54