Можно ли символически ссылаться на основной модуль Perl?

StackOverflow https://stackoverflow.com/questions/2943324

Вопрос

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

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

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

{$foo}(123);

против.

&{$foo}(123);

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

Спасибо.

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

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

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

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";
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top