Можно ли символически ссылаться на основной модуль Perl? - PullRequest
1 голос
/ 31 мая 2010

Я знаю, что могу легко сделать что-то вроде

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

и символически ссылаюсь на то, что для каждой функции мне нужно symb ref, но я просто хотел бы знать, есть ли способ сделать что-то вроде

{$foo}(123);

против

&{$foo}(123);

, который работает, но не для основных функций.

Спасибо.

Ответы [ 3 ]

6 голосов
/ 01 июня 2010

AFAIK нет, вы не можете это сделать. Из соображений производительности функции CORE никогда не смотрят на таблицу символов, ЕСЛИ во время компиляции не была объявлена ​​эквивалентная функция CORE::GLOBAL. К сожалению, вы должны написать эту CORE::GLOBAL функцию и правильно настроить ее для симуляции соглашений о вызовах реальной функции. Некоторые функции CORE не могут быть полностью воспроизведены без массовых взломов, например, print и open. Поскольку CORE::GLOBAL является глобальным и влияет на весь ваш код и весь библиотечный код, вы должны быть уверены, что получите точно правильно или очень трудно отлаживать ошибки. Некоторые модули, такие как autodie , должны идти на все, чтобы обернуться вокруг основных функций.

Но здесь, позвольте мне показать вам, где находятся шкафчик с оружием и боеприпасы ...

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

... конечно, это огромная дыра в безопасности и обслуживании. Не делай этого.

2 голосов
/ 31 мая 2010

Если я правильно прочитал этот вопрос , вы не сможете получить ссылку на встроенную функцию. Я подозреваю, что аналогичные трудности не позволят вам вызывать встроенные модули, используя символические ссылки.

Что касается использования символических ссылок для вызова кода, я бы предложил вам вместо этого использовать таблицу диспетчеризации. Например:

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 голосов
/ 01 июня 2010

Похоже, вам нужно переопределить основные функции во время компиляции, а затем вы можете поиграть с ними. Однако мне больше нравится подход к распределению хешей (или скаляров).

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