對於靜態範圍和動態範圍,與淺結合的情況下,爲什麼不試試呢?使用Perl靜態範圍:
my $x = 2;
my $y = 1;
sub f3($) {
my $z = shift;
$x = $z + $x + $y;
}
sub f2($$) {
my ($p, $z) = @_;
my $x = 5;
$p->($z);
}
sub f1($) {
my $z = shift;
my $y = $z;
f2(\&f3, $y);
}
f1(4);
print "$x\n";
我得到7
(這是4 + 2 + 1
)。如您所預測的,將my
s更改爲local
s以獲得具有淺綁定的動態範圍,我會得到2
。
使用深度綁定測試動態範圍比較棘手,因爲很少有語言支持它。在this answer a while back中,我發佈了Perl代碼,通過傳遞給標量的引用散列來「手動」實現深度綁定;使用同樣的方法:
#!/usr/bin/perl -w
use warnings;
use strict;
# Create a new scalar, initialize it to the specified value,
# and return a reference to it:
sub new_scalar($)
{ return \(shift); }
# Bind the specified procedure to the specified environment:
sub bind_proc(\%$)
{
my $V = { %{+shift} };
my $f = shift;
return sub { $f->($V, @_); };
}
my $V = {};
$V->{x} = new_scalar 2;
$V->{y} = new_scalar 1;
sub f3(\%$) {
my $V = shift;
my $z = $V->{z}; # save existing z
$V->{z} = new_scalar shift; # create & initialize new z
${$V->{x}} = ${$V->{z}} + ${$V->{x}} + ${$V->{y}};
$V->{z} = $z; # restore old z
}
sub f2(\%$$) {
my $V = shift;
my $p = shift;
my $z = $V->{z}; # save existing z
$V->{z} = new_scalar shift; # create & initialize new z
my $x = $V->{x}; # save existing x
$V->{x} = new_scalar 5; # create & initialize new x
$p->(${$V->{z}});
$V->{x} = $x; # restore old x
$V->{z} = $z; # restore old z
}
sub f1(\%$) {
my $V = shift;
my $z = $V->{z}; # save existing z
$V->{z} = new_scalar shift; # create & initialize new z
my $y = $V->{y}; # save existing y
$V->{y} = new_scalar ${$V->{z}}; # create & initialize new y
f2(%$V, bind_proc(%$V, \&f3), ${$V->{y}});
$V->{y} = $y; # restore old y
$V->{z} = $z; # restore old z
}
f1(%$V, 4);
print "${$V->{x}}\n";
__END__
我得到10
(這是4 + 2 + 4
)。
可能重複的[靜態和動態範圍](http://stackoverflow.com/questions/9421863/statically-and-dynamically-scopes) – skaffman 2012-02-23 22:09:22
它不是重複的,這是一個不同的問題。 – nullException 2012-02-23 23:15:00