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

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

Существует ли простой способ временно импортировать символы для блока, который автоволшебно заставил бы их уйти в конце блока, и который также обработал бы прототипы правильно?

6
задан friedo 14 June 2010 в 16:52
поделиться

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
1
ответ дан 16 December 2019 в 21:34
поделиться

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

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

4
ответ дан 16 December 2019 в 21:34
поделиться

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

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

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

1
ответ дан 16 December 2019 в 21:34
поделиться

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

use List::Util;
sub blah {
    print List::Util::max(@list);
}
2
ответ дан 16 December 2019 в 21:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: