6

List::Util::max多くのことを行う大規模なプログラムの途中など、便利なユーティリティ関数が必要になることがあります。だから私がするなら

use List::Util 'max';

プログラムの先頭で、そのシンボルに行き詰まり、名前空間全体を汚染しています。必要なのは 1 つのサブルーチンだけであるにもかかわらずです。

そのため、代わりに別のパターンを試すことを考えていました。

use List::Util ();

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

ただし、これには 2 つの問題があります。1 つは、ブロックの最後で自動的にインポートを解除しないことです (drat) unimport

もう 1 つの問題は、明らかにプロトタイプが正しく適用されないことmax( @foobar )です。

ブロックのシンボルを一時的にインポートする簡単な方法はありますか?ブロックの最後でシンボルを自動的に削除し、プロトタイプを正しく処理する方法はありますか?

4

4 に答える 4

4

これを行うだけで、はるかに良くてきれいになります:

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 バーディーが言及しています)。

于 2010-06-14T17:05:16.297 に答える
2

1つのサブルーチンでmaxのみを使用する場合、名前空間にはまったくインポートしません。私の解決策は

use List::Util;
sub blah {
    print List::Util::max(@list);
}
于 2010-06-15T16:11:18.557 に答える
1

perlfuncno MODULEは、あなたが望むことをするべきであることを意味します:

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

しかし、それは機能しません -- 少なくとも List::Util では機能しません。unimportメソッドを定義する必要があると思います。それでも、maxモジュール内のベアにさまざまな定義を呼び出すことができるかどうかはわかりません。

于 2010-06-14T18:03:29.680 に答える
1

シンボル テーブル エントリをローカライズできます。

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
于 2010-06-14T17:13:00.413 に答える