Perl:这段代码怎么可能工作?

Perl: How is it possible that this code is working?

my %hash = ('red' => "John", 'blue' => "Smith"); 
func (%hash);  

sub func {
    my $hash = $_[0];
    print "$hash{'red'}\n";
    print "$hash{'blue'}\n";
}

我向子例程发送了一个散列,这个散列被视为标量。如果是这样,我怎么可能通过调用它的键来转向散列中的值?

因为你的%hash范围是整个程序。

func(%hash);

相当于

func('red', 'John', 'blue', 'Smith'); 
   -or-
func('blue', 'Smith', 'red', 'John'); 

所以

my $hash = $_[0];

相当于

my $hash = 'red';
   -or-
my $hash = 'blue';

完全没用。幸好你再也不用 $hash 了。


相反,您使用在 sub 外部声明的 %hash。您可以通过重新排序代码或限制 %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.

解决方法是传递引用。

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

%hash is supposed to be local. no?

它在封闭范围内是局部的。范围由大括号分隔。但是你的声明周围没有大括号:

my %hash;

因此,%hash 在文件的每个嵌套范围内都可见。这是一个例子:

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