4

Perlbignum bigintbigratプラグマにはin_effect、ヒント ハッシュをプローブすることによって、プラグマがスコープにロードされているかどうかを検出する関数が含まれています。ただし、これはバージョン 5.9.4 以降の perl でのみ機能します。これは、レキシカル ヒント ハッシュが導入されたときからです。

これらのプラグマが以前のバージョンの perl で有効かどうかを判断する良い方法はありますか? 私の用途では、バージョン 5.8.8 までサポートしたいと思います。

更新: 以下の暴徒の解決策は、有効である可能性のある字句スペースにアクセスできる場合に機能bignumします。ただし、私のユースケースでは、そのスペースから呼び出される関数を作成しており、その関数内で呼び出し元のスコープがbignum読み込まれたかどうかを判断する必要があります。(つまり、私のコードではbignum::in_effect(2)、呼び出しスタックの数フレームを検索するようなものを呼び出しています)

 sub test_sub {is_bignum_in_effect_in_the_caller}
              # bignum::in_effect(1) in 5.9.4+

 test_sub(); # no bignum
 {use bignum; test_sub()}  # yes bignum
4

1 に答える 1

3

これが「良い」方法であるかどうかはわかりませんが、単純な操作を実行して、bigint/bigrat の結果または従来の Perl の結果が得られるかどうかを確認できます。

$bigint_enabled = length(1E20) == 21;   # conventional result is 5

この答えをさらに悪くするリスクがあるのですが、呼び出し元のスコープで bigint が有効になっているかどうかをどのように判断できますか?

1。bignum が有効になっているかどうかを発信者に伝える必要があります。

# あなたのパッケージ
package Foo;
use base 'Exporter';
use bigint;
our @EXPORT = qw($BIGINT_TEST multiply);
our $BIGINT_TEST = $]>=5.009004 
    ? "bigint::in_effect()"
    : "\$bigint::VERSION<0.22 || length(1E20)==21";

sub multiply {
    my ($arg1, $arg2, $bigint_enabled) = @_;
    if ($bigint_enabled) {
        use bigint;
        return $arg1*$arg2;
    } else {
        no bigint;
        return $arg1*$arg2;
    }
}

# user program
use Foo;
use bigint;
print "Enabled: ", multiply(1E15,1E10, eval $BIGINT_TEST), "\n";
{
    no bigint;
    print "Disabled: ", multiply(1E15,1E10,eval $BIGINT_TEST), "\n";
}

# result
$ perl510 user_program.pl
Enabled: 10000000000000000000000000
Disabled: 1e+25

$ perl587 user_program.pl      ($bignum::VERSION eq 0.07)
Enabled: 10000000000000000000000000
Disabled: 10000000000000000000000000

$ perl588 user_program.pl      (includes upgrade to bignum 0.25)
Enabled: 10000000000000000000000000
Disabled: 1e+25

二。ソースフィルタリング?op ツリーをハックしますか?これらのメソッドのいずれかを使用して、メソッド呼び出しに引数を挿入するか、メソッド呼び出しの前にグローバル変数を設定します。

于 2011-06-07T19:17:26.063 に答える