有没有办法在perl中将函数声明为变量?

Mah*_*hmi 2 perl function

例如,下面给出了伪代码。根据给 x 的输入,如果 x 是 func1,则必须调用 func1()。如果 x 是 func2,则必须调用 func2()。有没有办法做到这一点。我不想使用 if 或 switch case 语句。有没有其他方法可以根据用户输入进行函数调用?(类似于将函数视为变量?

sub func1()
{...}

sub func2() 
{...}

sub mainfunc()
{ 
   x = <STDIN>;
   x();
}
Run Code Online (Sandbox Code Playgroud)

zdi*_*dim 9

看起来您正在寻找调度表

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;

# Dereference the code-reference (run code) associated with $input value 
$option{$input}->();
Run Code Online (Sandbox Code Playgroud)

这里sub { ... }定义了一个匿名子程序并返回对代码引用。获取代码引用的另一种方法是获取命名子的引用,语法为\&sub-name。作为引用,它是(单值)标量类型,因此可以用作哈希值。

因此,当用户提供o1运行的是引用 ( sub { ... }) 中的代码时,它是o1散列中键的值,即$option{o1}.

运行代码引用的语法很像取消引用数组或散列引用

$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
Run Code Online (Sandbox Code Playgroud)

$cr此处的标量变量将具有代码引用my $cr = sub { ... }.


Sha*_*awn 6

安全的方法是将名称散列映射到子程序,这样恶意用户就无法调用任意子程序。就像是:

my %table = ("func1" => \&func1, "func2" => \&func2);
my $x = <STDIN>;
chomp $x;
if (exists $table{$x}) {
  $table{$x}->();
} else {
   # Handle error
}
Run Code Online (Sandbox Code Playgroud)