Лексический импорт полезных функций в большом скрипте

Иногда мне нужна полезная функция полезности, как 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 в вашем модуле вызовите разные определения.

Другие вопросы по тегам