Perl 在大脚本中按词汇导入有用函数 有时候,我需要一个有用的实用函数,比如代码>::UTI::Max < /C>在一个有很多东西的大程序的中间。所以如果我这样做了 use List::Util 'max';

Perl 在大脚本中按词汇导入有用函数 有时候,我需要一个有用的实用函数,比如代码>::UTI::Max < /C>在一个有很多东西的大程序的中间。所以如果我这样做了 use List::Util 'max';,perl,import,lexical-scope,Perl,Import,Lexical Scope,在我的程序顶部,我被这个符号卡住了,污染了我的整个名称空间,尽管我只需要在一个子例程中使用它 因此,我一直在考虑尝试一种不同的模式: use List::Util (); # a whole bunch of stuff later... sub blah { List::Util->import( 'max' ); $blah = max @foobar; ... } 不过,这有两个问题。首先,它不会在块(drat)的末尾自动取消导入。我必须使用取消导入来撤

在我的程序顶部,我被这个符号卡住了,污染了我的整个名称空间,尽管我只需要在一个子例程中使用它

因此,我一直在考虑尝试一种不同的模式:

use List::Util ();

# a whole bunch of stuff later...
sub blah { 
    List::Util->import( 'max' );
    $blah = max @foobar;
    ...
}
不过,这有两个问题。首先,它不会在块(drat)的末尾自动取消导入。我必须使用
取消导入
来撤消所有操作

另一个问题是,显然原型没有得到正确的应用,所以我不得不说
max(@foobar)
,而不是更漂亮的无括号版本


是否有一种简单的方法可以临时导入块的符号,这样可以自动使它们在块的末尾消失,也可以正确处理原型?

只需这样做,它会更好、更干净:

package Foo;
use strict; use warnings;
use List::Util 'max';
use namespace::autoclean;

# your method definitions here...
在包的编译周期完成后,将“取消”符号。在方法中对它的调用仍然有效,但是没有名称空间污染(删除了
*Foo::max
符号),调用
$obj->max()
将失败


或者,您可能想看一看(我对它一无所知;一个irc小鸟提到了它)。

您可以本地化符号表条目:

use List::Util ();

@y = qw(1 3 5 -9 4);

sub max { # return maximum *absolute value* of list
    my $max = abs(shift);
    $max<abs($_) && ($max=$abs($_))  for @_;
    return $max;
}

sub max2 {
    local *max = *List::Util::max;
    return max(@_);
}

print "My max:         ", max(@y), "\n";    # ==> 9
print "List::Util::max ", max2(@y), "\n";   # ==> 5
使用List::Util();
@y=qw(1 3 5-9 4);
sub max{#返回列表的最大*绝对值*
我的$max=abs(班次);
最多9美元
打印“List::Util::max”,max2(@y),“\n”;#=>5
意味着
任何模块
都不应执行您想要的操作:

sub blah {
    use List::Util qw(max);
    say max @foobar;
    no List::Util;
}

但这不起作用——至少对于List::Util不起作用。我认为它需要定义一个
不重要的
方法。即使如此,我也不确定是否可以在模块调用不同的定义中使用裸露的
max

如果只在一个子例程中使用max,我根本不会将其导入命名空间。我的解决方案是

use List::Util;
sub blah {
    print List::Util::max(@list);
}

如果
max
中有一个原型,这将引入微妙的错误,因为原型的效果在编译时会被烧掉。在
max2
中,使用的原型是
main::max
中的原型,而不是
List::Util::max
中的原型。很有帮助的是,您应该在赋值时得到一个关于原型不匹配的警告。@Eric Strom-Good point,那太糟糕了。小心使用
本地
子例程名称。虽然
名称空间::自动清理
很时髦,但它并不能解决主要问题,即
max
仍然存在于整个包中,而不是局限于单个块中,这正是我真正想要实现的。我希望我的实用程序函数是有类似的词汇变量。@friedo:为什么整个包都有
max
的问题?如果问题是名称空间污染,这就是这个模块要解决的问题。也许我想在包中的其他地方有一个不同的
max
。没错,这是一个实际的解决方案。但我只是想看看是否有什么办法g比实际更酷。:)啊,如果是为了酷,那么让讨论继续下去:
使用
行不会以不同的方式执行(前面)时间比子定义的其余部分都要长?
use
no
都发生在编译时;它们将在编译
blah
时执行。这仍然尊重原型,因此可以省去括号:print List::Util::max@List;