Лексический импорт полезных функций в большом скрипте - PullRequest
6 голосов
/ 14 июня 2010

Иногда мне нужна полезная служебная функция, такая как 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 голосов
/ 14 июня 2010

Просто сделайте это, это намного лучше и чище:

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-птичка).

2 голосов
/ 15 июня 2010

Если вы используете max только в одной подпрограмме, я бы вообще не импортировал ее в пространство имен.Мое решение -

use List::Util;
sub blah {
    print List::Util::max(@list);
}
1 голос
/ 14 июня 2010

perlfunc подразумевает, что no MODULE должен делать то, что вы хотите:

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

, но это не работает - по крайней мере, для List :: Util.Я считаю, что это должно было бы определить unimport метод.Даже в этом случае, я не уверен, что вы могли бы иметь в своем модуле голый max, вызывающий различные определения.

1 голос
/ 14 июня 2010

Вы можете локализовать запись таблицы символов:

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
...