我知道我可以轻松地做类似是否可以象征性地引用Perl核心模块?
sub sin {
sin($_[0]);
}
,并象征性地引用,对于每一个功能,我需要SYMB裁判,但我只是想知道是否有办法做到像
{$foo}(123);
与
&{$foo}(123);
它的工作原理,但不是核心功能。
谢谢。
我知道我可以轻松地做类似是否可以象征性地引用Perl核心模块?
sub sin {
sin($_[0]);
}
,并象征性地引用,对于每一个功能,我需要SYMB裁判,但我只是想知道是否有办法做到像
{$foo}(123);
与
&{$foo}(123);
它的工作原理,但不是核心功能。
谢谢。
AFAIK不,你不能这样做。出于性能原因,CORE
函数从不查看符号表,除非已在编译时声明了等效函数CORE::GLOBAL
。不幸的是,你必须编写这个函数,并且正确地模拟真实函数的调用约定。例如,某些CORE
功能无法在没有大规模黑客入侵的情况下完全复制,例如print
和open
。由于CORE::GLOBAL
是全球性的影响所有的代码和所有库代码,你必须确保得到它正是权利或导致很难调试的错误。一些模块,例如autodie,必须花费很多时间来包装核心功能。
但在这里,让我告诉你在哪里枪柜和弹药是...
my @return = eval "$function(\@args)";
...当然,这是一个巨大的安全性和可维护性孔。不要这样做。
我希望接受这个答案并不意味着你实际上要使用它。 – Schwern 2010-06-01 07:17:36
这是我想要的答案,就是这样。在任何普通程序中,我都不会使用你所建议的eval事物。但这些都是非凡的时代......它只是一个计算器脚本(while(1){our $ ans = eval
如果我正确读取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);
它看起来像你需要在编译时覆盖核心功能,然后你可以与他们摆弄。不过,我更喜欢调度哈希(或标量)方法。
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";
你怎么想这样做来实现呢?也许有不止一种方法可以做到这一点。 – daxim 2010-05-31 12:35:04
任何为什么要使用符号引用,这需要禁用'use strict'?为什么不使用代码引用而不是符号引用?为了重申daxim的问题,你最大的目标是什么? – FMc 2010-05-31 13:11:03
没有真正的目标,我只想知道它是否可能。我对符号引用的观点是,人阻止他们,因为: 一)他们是危险的(严格禁止它们)。 b)它们只能用于非词汇范围的变量。 c)你应该使用散列代替。 d)他们不是适当的参考。 所有四点并不适用于子程序。子已经在全球范围内,并没有引用计数(他们不,是吗?)。在大多数情况下,使用symb refs调用subs可以使你的代码更容易维护,比if($ foo eq“attack”){&attack} elsif(等等) – 2010-05-31 13:43:32