Лексический импорт полезных функций в большом скрипте
Иногда мне нужна полезная функция полезности, как 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 ответа
Вы можете локализовать запись таблицы символов:
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-птичка упомянула об этом).
Если вы используете max только в одной подпрограмме, я бы вообще не импортировал ее в пространство имен. Мое решение состоит в том, чтобы
use List::Util;
sub blah {
print List::Util::max(@list);
}
Perlfunc подразумевает, что no MODULE
следует делать то, что вы хотите:
sub blah {
use List::Util qw(max);
say max @foobar;
no List::Util;
}
но это не работает - по крайней мере, не для List::Util. Я считаю, что это должно было бы определить unimport
метод. Даже тогда я не уверен, что вы могли бы иметь max
в вашем модуле вызовите разные определения.