如果我运行下一个脚本:
use strict;
use warnings;
sub load {
use File::Path qw (make_path);
}
load();
make_path('1/2/3/4');
exit 0;
它完美地工作。我想将加载的模块的范围限制为子例程,以便我不能使用在加载它的子例程之外的模块中声明的子例程。可能吗?
简短的回答:不,这不可能。
长答案:加载 File::Path 后,您无法阻止代码调用File::Path::make_path()
,但您可以通过短名称限制它的可用范围。
use File::Path ();
sub load {
local *make_path = \&File::Path::make_path;
make_path('foo/bar/baz'); # This would work...
}
File::Path::make_path('bang/kapow'); # This would work too
make_path('xyxxy/plugh'); # But this would die
但是通过使用local
范围在词法上并不局限于语法代码块。它是动态范围的,这意味着所有被调用的代码load()
也将被make_path
视为一个工作子例程。
我建议不要使用这种技术,因为它有点晦涩,并且在远处可能会产生一些难以解释的副作用。我主要发现它对于编写单元测试很有用,它可以用来用模型替换某些功能。
Perl 开发人员正在讨论添加词法子作为语言的一部分。此功能应该让您几乎可以做任何您想做的事情,而不会出现使用local
. 但这仍在进行中,甚至在 perl 的开发版本中都不可用。
简而言之:你不能。更糟糕的是,use
它是在编译时执行的,所以你把它放在你的 sub 中没有任何区别(除了外观上的好处)。