"Smith"); func (%hash); sub func { my $hash = $_[0]; p...">

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?

+3


source to share


3 answers


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";
}

      

+12


source


Because your volume %hash

is the whole program.



+2


source


% 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

      

0


source







All Articles