在大脚本中词法导入有用的函数

发布于 2024-09-05 14:35:16 字数 563 浏览 9 评论 0原文

有时我需要一个有用的实用函数,例如在执行大量操作的大型程序中的 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 ) 而不是更漂亮的无括号版本。

有没有一种简单的方法可以临时导入块的符号,这会自动使它们在块的末尾消失,并且还能正确处理原型?

Sometimes I need a useful utility function, like List::Util::max in the middle of a large program that does lots of stuff. So if I do

use List::Util 'max';

At the top of my program, I'm stuck with that symbol, polluting my whole namespace, even though I only need it in one subroutine.

So I've been thinking of trying a different pattern, instead:

use List::Util ();

# a whole bunch of stuff later...
sub blah { 
    List::Util->import( 'max' );
    $blah = max @foobar;
    ...
}

There are two problems with this, though. For one, it doesn't automatically unimport at the end of the block (drat.) I would have to undo everything with an unimport.

The other problem is that apparently prototypes don't get applied correctly, so I have to say max( @foobar ) instead of the prettier parenthesisless version.

Is there an easy way to temporarily import symbols for a block, which would automagically make them go away at the end of the block, and which would also handle prototypes correctly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

玻璃人 2024-09-12 14:35:17

只要这样做,它就更好更干净:

package Foo;
use strict; use warnings;
use List::Util 'max';
use namespace::autoclean;

# your method definitions here...

namespace::autoclean 将“unimport” " 包编译周期完成后的符号。在您的方法中对它的调用仍然有效,但您没有命名空间污染(*Foo::max 符号被删除)并调用 $obj->max()将会失败。

或者,您可能想看看 Lexical::Import (我知道没有任何关于它的内容;irc 小鸟提到了它)。

Just do this, it's much better and cleaner:

package Foo;
use strict; use warnings;
use List::Util 'max';
use namespace::autoclean;

# your method definitions here...

namespace::autoclean will "unimport" the symbol after the package's compilation cycle is done. The call to it in your method will still work, but you have no namespace pollution (the *Foo::max symbol is removed) and calling $obj->max() will fail.

Alternatively, you might want to take a look at Lexical::Import (I know nothing about it; an irc birdie mentioned it).

洋洋洒洒 2024-09-12 14:35:17

如果您只在一个子例程中使用 max,我根本不会将其导入到命名空间中。我的解决方案是

use List::Util;
sub blah {
    print List::Util::max(@list);
}

If you only use max in one subroutine, I wouldn't import it into the namespace at all. My solution is to

use List::Util;
sub blah {
    print List::Util::max(@list);
}
度的依靠╰つ 2024-09-12 14:35:17

您可以本地化符号表条目:

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

You can localize a symbol table entry:

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
澉约 2024-09-12 14:35:17

perlfunc 意味着没有 MODULE应该做你想做的事:

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

但这不起作用——至少对 List::Util 不起作用。我相信它需要定义一个 unimport 方法。即使如此,我也不确定您的模块中是否可以有一个裸露的 max 调用不同的定义。

perlfunc implies that no MODULE should do what you want:

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

but that doesn't work -- at least not for List::Util. I believe that it would need to define an unimport method. Even then, I'm not sure if you could have a bare max in your module call different definitions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文