2010-05-31 53 views
1

我知道我可以轻松地做类似是否可以象征性地引用Perl核心模块?

sub sin { 
    sin($_[0]); 
} 

,并象征性地引用,对于每一个功能,我需要SYMB裁判,但我只是想知道是否有办法做到像

{$foo}(123); 

&{$foo}(123); 

它的工作原理,但不是核心功能。

谢谢。

+1

你怎么想这样做来实现呢?也许有不止一种方法可以做到这一点。 – daxim 2010-05-31 12:35:04

+2

任何为什么要使用符号引用,这需要禁用'use strict'?为什么不使用代码引用而不是符号引用?为了重申daxim的问题,你最大的目标是什么? – FMc 2010-05-31 13:11:03

+0

没有真正的目标,我只想知道它是否可能。我对符号引用的观点是,人阻止他们,因为: 一)他们是危险的(严格禁止它们)。 b)它们只能用于非词汇范围的变量。 c)你应该使用散列代替。 d)他们不是适当的参考。 所有四点并不适用于子程序。子已经在全球范围内,并没有引用计数(他们不,是吗?)。在大多数情况下,使用symb refs调用subs可以使你的代码更容易维护,比if($ foo eq“attack”){&attack} elsif(等等) – 2010-05-31 13:43:32

回答

6

AFAIK不,你不能这样做。出于性能原因,CORE函数从不查看符号表,除非已在编译时声明了等效函数CORE::GLOBAL。不幸的是,你必须编写这个函数,并且正确地模拟真实函数的调用约定。例如,某些CORE功能无法在没有大规模黑客入侵的情况下完全复制,例如printopen。由于CORE::GLOBAL是全球性的影响所有的代码和所有库代码,你必须确保得到它正是权利或导致很难调试的错误。一些模块,例如autodie,必须花费很多时间来包装核心功能。

但在这里,让我告诉你在哪里枪柜和弹药是...

my @return = eval "$function(\@args)"; 

...当然,这是一个巨大的安全性和可维护性孔。不要这样做。

+6

我希望接受这个答案并不意味着你实际上要使用它。 – Schwern 2010-06-01 07:17:36

+0

这是我想要的答案,就是这样。在任何普通程序中,我都不会使用你所建议的eval事物。但这些都是非凡的时代......它只是一个计算器脚本(while(1){our $ ans = eval ; say $ ans})一分钟为我自己,与一些AUTOLOAD的功能,如asin,acos等。我只是想要最少的打字来完成这些功能,并评估工作。 – 2010-06-01 13:43:44

2

如果我正确读取this SO question,你不能把一个内置函数的引用。我怀疑类似的困难会阻止你使用符号引用调用内置插件。

关于使用符号引用来调用代码,我会建议你使用一个调度表代替。例如:

use strict; 
use warnings; 

sub sin_deg { sin $_[0] * atan2(1, 1)/45 } 

my %dt = (
    sin_deg => \&sin_deg, 
    attack => sub { print "Attacking: @_\n" }, 
); 

print $dt{sin_deg}->(60), "\n"; 

$dt{attack}->(1, 2, 3); 
0

它看起来像你需要在编译时覆盖核心功能,然后你可以与他们摆弄。不过,我更喜欢调度哈希(或标量)方法。

use strict; 
use warnings; 

our $s; 
BEGIN { 
    *CORE::GLOBAL::sin= sub { sin($_[0])*2 }; 
    *CORE::GLOBAL::cos= sub { cos($_[0])*2 }; 
    our $s= *CORE::GLOBAL::sin; 
} 

*CORE::GLOBAL::sin= *CORE::GLOBAL::cos; 
print sin(0.01)."\n"; 
print $s->(0.01)."\n"; 
相关问题