Perl 的 bignum
bigint
和 bigrat
pragmas 有用地包含一个 in_effect
该函数将通过探测提示哈希来检测编译指示是否已加载到作用域中。但是,这只适用于 5.9.4 及更高版本的 perl,因为那时引入了词法提示哈希。
有什么好的方法可以确定这些 pragma 在早期版本的 perl 中是否有效?对于我的用途,我想支持回 5.8.8 版。
更新:如果我可以访问 bignum
的词法空间,下面的 mob 解决方案将起作用。可能有效。但是,对于我的用例,我正在编写一个将从该空间调用的函数,并且在该函数内部我需要确定调用者的作用域是否具有 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
最佳答案
我不知道这是否是一种“好”的方法,但是您可以进行一个简单的操作,看看您得到的是 bigint/bigrat 结果还是传统的 Perl 结果。
$bigint_enabled = length(1E20) == 21; # conventional result is 5
冒着使这个答案变得更糟糕的风险,您如何确定是否在调用者的范围内启用了 bigint?
一。要求调用者告诉您是否启用了 bignum。
# your package
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 树?使用这些方法中的任何一种来向方法调用插入参数或在方法调用之前设置全局变量。
关于perl - 在 Perl 中,如何检测是否在 5.9.4 之前的版本中加载了 bignum 支持?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6270125/