问题复现:
#!/usr/bin/perl
use warnings;
use strict;
sub fun {
my $var = "hello world";
doSth();
sub doSth {
print "var: $var\n";
}
}
fun();
报错信息:Variable "$var" will not stay shared at t.pl line 11.
出错原因
perl
的sub
声明是全局的,在fun()
中声明的doSth()
不是fun()
的私有函数
第一次调用fun()
时声明doSth()
,并且其$var
变量是第一次fun()
中的'hello world'
如果第二次调用fun()
,此时doSth()
已经存在,不会再次声明,而此时调用doSth()
打印的并不是此刻fun()中的$var
,而是第一次fun()
中的$var
.之后的调用doSth
已经和fun
无关了,而且sub
声明的doSth
可以在任何地方使用
使用如下代码测试以上分析
#!/usr/bin/perl
use warnings;
use strict;
sub fun {
my $var = shift || "hello world";
print "fun var: $var\n";
sub doSth {
print "$var\n";
}
doSth();
}
fun();
fun("two");
fun("three");
输出:
Variable "$var" will not stay shared at t.pl line 19.
fun var: hello world
hello world
fun var: two
hello world
fun var: three
hello world
解决方案
#!/usr/bin/perl
use warnings;
use strict;
sub fun {
my $var = shift || "hello world";
## 使用闭包
my $doSth = sub {
print "var: $var\n";
};
$doSth->();
}
fun();
fun("two");
fun("three");
或者
#!/usr/bin/perl
use warnings;
use strict;
sub fun {
my $var = shift || "hello world";
## 使用符号表的类型团
no strict "refs";
*doSth = sub {
print "$var\n";
};
print "fun var: $var\n";
doSth();
}
fun();
fun("two");
fun("three");
或者
## 通过词法作用域变量控制
{
my $var;
sub fun {
$var = shift || "hello world";
doSth();
}
sub doSth {
print "$var\n";
}
}
fun();
fun("two");
fun("three");
解决方案在stackoverflow找到
http://stackoverflow.com/questions/25399728/perl-variable-will-not-stay-shared