Есть ли способ объявить функцию как переменную в perl? - PullRequest
2 голосов
/ 26 февраля 2020

Например, псевдокод приведен ниже. На основании входных данных, заданных для x, если x равен func1, то должна быть вызвана func1 (). Если x равен func2, то должна быть вызвана func2 (). Есть какой-либо способ сделать это. Я не хочу использовать оператор if или switch case. Есть ли другой способ сделать вызов функции на основе ввода пользователя? (что-то вроде обработки функции как переменной?

sub func1()
{...}

sub func2() 
{...}

sub mainfunc()
{ 
   x = <STDIN>;
   x();
}

Ответы [ 2 ]

9 голосов
/ 26 февраля 2020

Похоже, вы ищете таблицу отправки

use warnings;
use strict;
use feature 'say';

my %option = (
    o1 => sub { say "Code for func1, to run for key 'o1'"; },
    o2 => sub { say "Code that should run for input 'o2'"; },
    #...
);

my $input = <STDIN>;
chomp $input;

$option{$input}->();  # run code in reference associated with $input's value

Здесь sub { ... } определяет анонимную подпрограмму и возвращает ссылку на код . Будучи ссылкой, это скалярный (однозначный) тип, поэтому его можно использовать как значение ha sh.

Поэтому, когда пользователь вводит o1, запускается код в ссылке (sub { ... }), который является значением для ключа o1 в га sh, то есть $option{o1}.

Синтаксис для запуска ссылки на код очень похож на разыменование массива или ссылки ha sh

$ar->[0]     # dereference array reference, for the first element
$hr->{key}   # dereference hash  reference, for value for key 'key'
$cr->(LIST)  # dereference code  reference, to run with arguments in LIST

Скалярная переменная $cr здесь будет иметь ссылку на код, my $cr = sub { ... } .

6 голосов
/ 26 февраля 2020

Безопасный способ - это иметь sh имен, сопоставляемых с подпрограммами, чтобы злоумышленник не мог вызывать произвольные подпрограммы. Что-то вроде:

my %table = ("func1" => \&func1, "func2" => \&func2);
my $x = <STDIN>;
chomp $x;
if (exists $table{$x}) {
  $table{$x}->();
} else {
   # Handle error
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...