Perl: How is it possible that this code works?
my %hash = ('red' => "John", 'blue' => "Smith");
func (%hash);
sub func {
my $hash = $_[0];
print "$hash{'red'}\n";
print "$hash{'blue'}\n";
}
I send a hash to a subroutine and this hash is treated as a scalar. If so, how is it possible that I can access the value in the hash by calling its key?
source to share
func(%hash);
equivalent to
func('red', 'John', 'blue', 'Smith');
-or-
func('blue', 'Smith', 'red', 'John');
So
my $hash = $_[0];
equivalent to
my $hash = 'red';
-or-
my $hash = 'blue';
It's completely useless. Good thing you never use again $hash
.
Instead, you use the %hash
declared outside sub. You can see this by modifying your code or by limiting the scope %hash
.
use strict;
use warnings;
{
my %hash = ('red' => "John", 'blue' => "Smith");
func(%hash);
}
sub func {
my $hash = $_[0];
print "$hash{'red'}\n";
print "$hash{'blue'}\n";
}
$ perl a.pl
Global symbol "%hash" requires explicit package name at a.pl line 11.
Global symbol "%hash" requires explicit package name at a.pl line 12.
Execution of a.pl aborted due to compilation errors.
The solution is to pass the link.
use strict;
use warnings;
{
my %hash = ('red' => "John", 'blue' => "Smith");
func(\%hash);
}
sub func {
my $hash = $_[0];
print "$hash->{'red'}\n";
print "$hash->{'blue'}\n";
}
source to share
% hash is assumed to be local. not?
It is local to the enclosing scope. Areas are delimited by curly braces. But there are no bindings in your application:
my %hash;
The result is %hash
displayed inside each nested area in the file. Here's an example:
use strict;
use warnings;
use 5.016;
my $str = "hello";
if (1) { #new scope starts here
say "if: $str";
} #scope ends here
{ #new scope starts here
my $planet = "world";
say "block: $str";
for (1..2) { #new scope starts here
say "for: $str $planet";
} #scope ends here
} #scope ends here
#say $planet; #The $planet that was previously declared isn't visible here, so this looks
#like you are trying to print a global variable, which results in a
#compile error, because global variables are illegal with: use strict;
--output:--
if: hello
block: hello
for: hello world
for: hello world
source to share