将带有参数的子例程推入Perl中的堆栈

h q*_*h q 3 perl subroutine perl-data-structures

我想将带有参数的子程序推入堆栈,但我无法弄清楚语法.考虑一个没有参数的工作示例:

#!/usr/bin/perl -w
use strict;
use warnings;

sub hi    { print "hi\n";    }
sub hello { print "hello\n"; }
sub world { print "world\n"; }

my @stack;
push (@stack, \&hi   );
push (@stack, \&hello);
push (@stack, \&world);

while (@stack) {
    my $proc = pop @stack;
    $proc->();
}
Run Code Online (Sandbox Code Playgroud)

当我运行代码时:

% ./pop-proc.pl
world
hello
hi
Run Code Online (Sandbox Code Playgroud)

现在我的问题是,如果子程序看起来像这样:

sub mysub 
{
    chomp( my( $arg ) = @_ );
    print "$arg\n"; 
}
Run Code Online (Sandbox Code Playgroud)

我想用参数推送子程序,例如:

mysub("hello");
mysub("world");
Run Code Online (Sandbox Code Playgroud)

您的意见非常感谢.

ike*_*ami 8

使用匿名子(甚至可能是一个闭包).

push @stack, sub { mysub("hello") };
push @stack, sub { mysub("world") };
Run Code Online (Sandbox Code Playgroud)

例如,

sub hi { say "@_" }
my $arg = "Hello";
my $sub = sub { hi($arg, @_) };
$sub->("World");   # Hello World
Run Code Online (Sandbox Code Playgroud)


bri*_*foy 7

我可能会做这样的事情,我创建一个元组来保存代码引用及其参数:

use v5.24;

sub hi    { print "Hi @_\n";    }
sub hello { print "Hello @_\n"; }

my @stack;
push @stack, [ \&hi,    'Perl'     ];
push @stack, [ \&hello, 'Amelia'   ];
push @stack, [ \&hello, $ENV{USER} ];

while (@stack) {
    my( $proc, @args ) = pop( @stack )->@*;
    $proc->( @args );
}
Run Code Online (Sandbox Code Playgroud)

我在那里使用v5.24 后缀解除引用,但那是因为我无法自拔.这也有效,但现在我觉得它非常难看:

    my( $proc, @args ) = @{ pop( @stack ) };
Run Code Online (Sandbox Code Playgroud)

  • 将`use v5.24;`替换为`use feature qw(postderef); #5.20 +`和`没有警告qw(experimental :: postderef); #从5.24`开始不再具有实验性,您的代码将在5.20+中运行 (2认同)