4

Perlbignum bigintbigratpragma 有用地包含一个in_effect函数,该函数将通过探测提示哈希来检测 pragma 是否加载到作用域中。然而,这只适用于 perl 的 5.9.4 及更高版本,因为那是引入词法提示哈希的时候。

有没有什么好的方法可以确定这些 pragma 在早期版本的 perl 中是否有效?对于我的使用,我想支持回到 5.8.8 版本。

更新:如果我可以访问可能有效的词汇空间,则下面的 mob 解决方案将起作用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?

一。要求调用者告诉你是否启用了 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

二。源过滤?破解操作树?使用这些方法中的任何一种来向方法调用插入一个参数或在方法调用之前设置一个全局变量。

于 2011-06-07T19:17:26.063 回答