开发者

Is it possible to symbolically reference a Perl core module?

开发者 https://www.devze.com 2023-01-01 09:46 出处:网络
I know I could easily do something like sub sin { sin($_[0]); } and symbolically reference that for every function I need to symb ref, but I\'d just like to know if there\'s a way to do something l

I know I could easily do something like

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

and symbolically reference that for every function I need to symb ref, but I'd just like to know if there's a way to do something like

{$foo}(123);

vs.

&{$foo}(123);

which w开发者_StackOverflow中文版orks, but not for core functions.

Thanks.


AFAIK no, you can't do it. For performance reasons, CORE functions never look at the symbol table UNLESS an equivalent CORE::GLOBAL function has been declared at compile time. Unfortunately, you have to write that CORE::GLOBAL function and get it just right to simulate the calling conventions of the real function. Some CORE functions cannot be entirely reproduced without massive hacks, print and open for example. Since CORE::GLOBAL is global an effects all your code and all library code you have to be sure to get it exactly right or cause very hard to debug errors. Some modules, such as autodie, have to go to great lengths to wrap around core functions.

But here, let me show you where the gun locker and ammo are...

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

...of course, this is a massive security and maintainability hole. Don't do it.


If I read this SO question correctly, you cannot take a reference to a built-in function. I suspect that analogous difficulties will prevent you from invoking built-ins using symbolic references.

Regarding the use of symbolic references to invoke code, I would suggest that you use a dispatch table instead. For example:

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);


It looks like you need to override the core functions at compile time, and then you can fiddle with them. I like the dispatch hash (or scalar) approach better, though.

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";
0

精彩评论

暂无评论...
验证码 换一张
取 消