Иногда мне нужна полезная служебная функция, как 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;
...
}
Существует две проблемы с этим, все же. Для одного это автоматически не не импортирует в конце блока (черт бы побрал). Я должен был бы отменить все с unimport
.
Другая проблема состоит в том, что, по-видимому, прототипы не становятся прикладными правильно, таким образом, я должен сказать max( @foobar )
вместо более симпатичной версии без круглой скобки.
Существует ли простой способ временно импортировать символы для блока, который автоволшебно заставил бы их уйти в конце блока, и который также обработал бы прототипы правильно?
Вы можете локализовать запись в таблице символов:
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
Просто сделайте это, это намного лучше и чище:
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).
perlfunc подразумевает, что no MODULE
должен делать то, что вы хотите:
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);
}