2011-06-07 14 views
4

Perl的bignumbigintbigrat编译指南有用地包含一个in_effect函数,该函数将通过探测提示哈希来检测该编译指示是否加载到作用域中。但是,这只适用于perl的5.9.4及更高版本,因为那时引入了词汇提示哈希。在Perl中,如何在5.9.4之前的版本中检测是否加载了bignum?

是否有任何确定这些编译指示是否在早期版本的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 

回答

3

我不知道这是否有资格作为一个“好”的方式,但你可以做一个简单的操作,看看你是否得到了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树?使用这些方法中的任何一个将方法调用的参数插入或在方法调用之前设置全局变量。

+0

有没有什么办法可以在来电者的词汇空间中做到这一点?我正在编写一个函数,需要知道它是否从已加载bignum的作用域调用。 – 2011-06-07 19:56:57

+0

首先,如果'$ bignum :: VERSION <0.22',那么'bigint'和'bigrat'不是词法范围的,你不需要为调用者的范围单独测试。当调用者使用Perl 5.8时,这很可能(虽然不是确定的)。 – mob 2011-06-07 20:21:18

相关问题