Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何将模块范围限制为子例程?_Perl_Scope - Fatal编程技术网

Perl 如何将模块范围限制为子例程?

Perl 如何将模块范围限制为子例程?,perl,scope,Perl,Scope,如果我运行下一个脚本: use strict; use warnings; sub load { use File::Path qw (make_path); } load(); make_path('1/2/3/4'); exit 0; 它工作得很好。我想将加载模块的范围限制在子例程中,这样我就不能在加载它的子例程之外使用模块中声明的子例程。可能吗?简言之:你不能。更糟糕的是,use是在编译时执行的,所以把它放在sub中没有任何区别(除了表面上的好处) 简短回答:不,这是不可能

如果我运行下一个脚本:

use strict;
use warnings;

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

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

exit 0;

它工作得很好。我想将加载模块的范围限制在子例程中,这样我就不能在加载它的子例程之外使用模块中声明的子例程。可能吗?

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

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

长答案:加载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\u path
视为一个工作子例程

我建议不要使用这种技术,因为它有点晦涩难懂,而且在远处会产生一些难以解释的副作用。我发现它在编写单元测试时非常有用,在单元测试中,可以用实体模型替换某些函数


Perl开发人员正在讨论将词法sub添加为语言的一部分。此功能应允许您几乎做您想做的事情,而不会出现使用
local
的问题。但这项工作仍在进行中,甚至在perl的开发版本中都不可用。

您是想在脚本中完成这项工作(根据您的示例),还是想将其归结为基础工作,这样做是为了使加载的模块不会将垃圾方法注入到对象模块的命名空间中?我会帮你处理后者的。@Oesor,我只是好奇而已。但是非常感谢你。我发现这个模块非常有用。顺便说一句,正在为5.18开发词法子程序!