将值绑定到Perl中的函数

tit*_*coy 3 perl

我使用类似于下面的哈希表来存储可以在提示符处输入的字母以及该选项的描述和将被调用的函数.

my %main_menu = (
    "l" => ["list locks", \&list_locks],
    "n" => ["new lock", \&new_lock],
    "u" => ["update lock", \&update_lock]
    );
Run Code Online (Sandbox Code Playgroud)

menu_prompt(\%main_menu) 生成以下菜单:

 ________________________ 
| l - list locks         |
| n - new lock           |
| u - update lock        |
|________________________|
(l,n,u)> 
Run Code Online (Sandbox Code Playgroud)

当用户输入"u"时,在提示符下将调用update_lock函数.

现在,我想用新的哈希表(%lock_menu)生成一个类似的菜单.但是,我将首先提示用户输入他们希望更新的锁的ID.

Please enter the ID of a lock to update: 1

You are updating lock 1.
 __________________ 
| l - list users   |
| n - new user     |
|__________________|
(p,u,c)> 

我想存储锁ID,以便锁定菜单功能可以访问它.例如:

my %users_menu = (
 "l" => ["list users", \&list_users],
 "n" => ["new user", \&new_user]);

我无法弄清楚如何将锁ID附加到中的函数%users_menu.因此,当选择"l"时,将使用该数字作为其第一个参数调用list_users.

我似乎记得ML,如果你在ML语言中调用一个n参数函数,只有一个参数,它将产生一个带有n-1个参数的函数.因此,例如,将func(int,int,int)作为func(5)调用将产生func(int,int),第一个参数保存为5.

在Perl中这可能吗?或者我是以错误的方式来做这件事的?请告诉我.

更新:这是打印菜单(print_options),提示用户输入字母并调用相应功能的功能.

sub menu_prompt
{
    my $options = shift;

    print_options $options;

    my $choice = <>;
    chomp $choice;

    if (defined $$options{$choice})
    {
        $$options{$choice}[1](); # no arguments
    }
}
Run Code Online (Sandbox Code Playgroud)

我想找到一种方法来为所有菜单使用此函数,而不是编写一个单独的函数,其中值传递给函数.

Eri*_*rom 6

没有发布更多的示例代码很难给出完整的答案,但是当你从哈希调用你的sub时,为什么不传递它的锁定值呢?

my $num = ... # get lock number;

$users_menu{"n"}[1]->($num)

# calls "new_user" passing it $num
Run Code Online (Sandbox Code Playgroud)

问题编辑:

sub menu_prompt {
    my $options = shift;

    print_options $options;

    my $choice = <>; # i assume the diamond operator got stripped
    chomp $choice;   # second my is in error

    if (defined $$options{$choice}) {
        return $$options{$choice}[1](@_); 
             # any additional arguments to menu_prompt will be passed to the sub
             # return the value for future processing
    }
}
Run Code Online (Sandbox Code Playgroud)


zen*_*zen 6

你想要咖喱功能.

有许多CPAN模块(见帖子末尾)用于currying.这是关闭咖喱的一个例子.

sub curry {
    my $f = shift;
    my $a = shift;
    sub { $f->( $a, @_ ); }
}


my ($input, $func);
$input = 2;
$func  = curry( sub { print join "\n", @_ }, $input );

$input = 12;
$func  = curry( $func , $input );

$input = 99;

$func->(4,6,8,10,19);


#outputs
2
12
4
6
8
10
19
Run Code Online (Sandbox Code Playgroud)

另请参见Data :: Util,Sub :: CurriedSub :: Curry.

HTH