4

如果我运行下一个脚本:

use strict;
use warnings;

sub load {
    use File::Path qw (make_path);
}

load();
make_path('1/2/3/4');

exit 0;

它完美地工作。我想将加载的模块的范围限制为子例程,以便我不能使用在加载它的子例程之外的模块中声明的子例程。可能吗?

4

2 回答 2

11

简短的回答:不,这不可能。

长答案:加载 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 的开发版本中都不可用。

于 2012-09-27T13:49:22.660 回答
4

简而言之:你不能。更糟糕的是,use它是在编译时执行的,所以你把它放在你的 sub 中没有任何区别(除了外观上的好处)。

于 2012-09-27T13:36:01.317 回答