Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between %hash and \%hash as a parameter?

Tags:

syntax

perl

I'm currently trying to learn Perl and I noticed that sometimes people "escape" variables when passing them as parameters. I first noticed this using SQL::Abstract:

my %hash = (
  'foo' => 'bar'
);
$db->insert('table', \%hash);

And now, searching for a "print_r" (PHP) equivalent in Perl and seeing people recommend Data::Dumper, I couldn't understand why people would think they're equivalent until I saw an example using print Dumper(\%hash); instead of print Dumper(%hash);.

This:

my %hash = (
  key1 => 'value1',
  key2 => 'value2'
);
print Dumper(%hash);

Outputs this:

$VAR1 = 'key2';
$VAR2 = 'value2';
$VAR3 = 'key1';
$VAR4 = 'value1';

But print Dumper(\%hash); outputs this:

$VAR1 = {
          'key2' => 'value2',
          'key1' => 'value1'
        };

Can someone explain exactly what is this and what's happening? I can't find this on my Perl book and don't even know what to search for on Google. Thanks.

like image 302
Ricky Avatar asked Jan 19 '11 01:01

Ricky


1 Answers

Borrowing from Ether's comment - look at the Perl References Tutorial, and later at Perl References Manual in the language specification. Or use perldoc perlreftut and perldoc perlref at the command line.


When you pass %hash, Perl passes a possibly large number of elements to the called function, which correspond to the key/value pairs.

When you pass \%hash, Perl passes a reference to a hash - essentially the address of the hash.

For example:

my %hash = ( Key1 => "Value1", Key2 => "Value2" );
sub counter
{
    printf "Count: %d\n", scalar(@_);
}
counter(%hash);
counter(\%hash);

which generates:

Count: 4
Count: 1

There are multiple ways you can get at the data:

sub hashref
{
    my($ref) = @_;
    foreach my $key (keys %{$ref})
    {
         print "$key: $ref->{$key}\n";
    }
}

sub hashnonref
{
    my(%hash) = @_;
    foreach my $key (keys %hash)
    {
        print "$key: $hash{$key}\n";
    }
}

sub hashasarray
{
    my(@array) = @_;
    foreach my $value (@array)
    {
         print "Value: $value\n";
    }
}

hashref(\%hash);   # Same data as before
print "\n";
hashnonref(%hash);
hashasarray(%hash);

Extra output:

Key2: Value2
Key1: Value1

Key1: Value1
Key2: Value2
Value: Key2
Value: Value2
Value: Key1
Value: Value1
like image 86
Jonathan Leffler Avatar answered Oct 27 '22 13:10

Jonathan Leffler