6

有时我需要一个有用的实用函数,比如List::Util::max在一个做很多事情的大程序中间。所以如果我这样做

use List::Util 'max';

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

所以我一直在考虑尝试不同的模式,而不是:

use List::Util ();

# a whole bunch of stuff later...
sub blah { 
    List::Util->import( 'max' );
    $blah = max @foobar;
    ...
}

不过,这有两个问题。一方面,它不会在块的末尾自动取消导入(drat)。我必须使用unimport.

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

有没有一种简单的方法可以临时导入块的符号,这会自动使它们在块的末尾消失,并且还能正确处理原型?

4

4 回答 4

4

只需这样做,它会更好更清洁:

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

# your method definitions here...

namespace::autoclean将在包的编译周期完成后“取消导入”符号。在您的方法中对它的调用仍然有效,但您没有命名空间污染(*Foo::max符号被删除)并且调用$obj->max()将失败。

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

于 2010-06-14T17:05:16.297 回答
2

If you only use max in one subroutine, I wouldn't import it into the namespace at all. My solution is to

use List::Util;
sub blah {
    print List::Util::max(@list);
}
于 2010-06-15T16:11:18.557 回答
1

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

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
于 2010-06-14T17:13:00.413 回答
1

perlfunc暗示no MODULE应该做你想做的事:

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

but that doesn't work -- at least not for List::Util. I believe that it would need to define an unimport method. Even then, I'm not sure if you could have a bare max in your module call different definitions.

于 2010-06-14T18:03:29.680 回答