如何通过在perl中引用来正确调用sub?

时间:2011-12-29 06:03:51

标签: perl reference

我正在处理一个调度脚本,它需要一个带有命令的字符串,对它做一些烹饪,然后解析它。但我无法抓住引用:

Use::strict;
Use:warnings;

my($contexto,$cmd,$target,$ultpos,@params);
my $do= "echo5 sample string that says stuff ";

$target="";
$cmd="";
$_="";
# i do some cumbersome string parsing to get the array with the exploded string and then call parsear(@command)

sub parsear{

my %operations=(
'echo' => \&echo,
'status' => \&status,
'echo5' => \&echo5,
);

my $op= $_[0];
if ($operations{$op}){
    $operations{$op}->(@_);
    print "it exists\n";
}else{
    print "incorrect command.\n";
    }
}




sub status{
    print "correct status.\n";
}

sub echo{
    shift(@_);
    print join(' ',@_) . "\n";
}

sub echo5{
    shift(@_);
    print join(' ',@_) . "\n" x 5;
}

我真的不知道问题是什么,如果sub不存在,它永远不会说“不正确的命令”,如果我打电话给例如“echo5 hello”它应该打印出来

hello
hello
hello
hello
hello

但它什么也没做。

当我打电话给回声时,它会起到推崇作用。有人可以向我解释这个魔法吗? 注意:我正在使用最新版本的草莓perl

2 个答案:

答案 0 :(得分:2)

use strict;  # use is a keyword
use warnings;

# all these variables are not needed

sub parsear {  # learn to indent correctly
    my %operations = (
        'echo'   => \&echo,
        'status' => \&status,
        'echo5'  => \&echo5,
    );
    my $op = shift;  # take first element off @_
    if ($operations{$op}) {
        print "$op exists\n";  # make your status msg useful
        $operations{$op}->(@_);
    } else {
        print "incorrect command: $op\n";  # and your error msg
    }
}    

sub status {
    print "correct status.\n";
}

sub echo {
    # shift(@_); # this is no longer needed, and now echo can be used as a
                 # normal subroutine as well as a dispatch target
    print join(' ',@_) . "\n";
}

sub echo5 {
    # shift(@_); # this is no longer needed
    print +(join(' ',@_) . "\n") x 5;  # parens needed since x binds tightly
}

然后运行:

parsear 'status';
parsear 'echo', 'hello';
parsear 'echo5', 'hello';
parsear 'an error';

结果:

status exists
correct status.
echo exists
hello
echo5 exists
hello
hello
hello
hello
hello
incorrect command: an error

我不确定你正在做什么cumbersome string parsing因为你没有包含它,但是如果你要解析像

那样的字符串
my $do = "echo5 sample string that says stuff ";

其中命令是第一个单词,参数是其余的,你可以拆分所有内容:

parsear split /\s+/, $do;

或使用正则表达式删除第一个单词:

my ($cmd, $arg) = $do =~ /^(\w+)\s*(.*)/;

parsear $cmd => $arg;

你甚至不需要变量:

parsear $do =~ /^(\w+)\s*(.*)/;

最后,echo5子程序比它需要的要复杂一些。它可以写成:

sub echo5 {
    print "@_\n" x 5;  # "@_" means join($", @_) and $" defaults to ' '
}

答案 1 :(得分:0)

x命令与你的期望不同;你可能想要:

print ((join(' ', @_) . "\n") x 5);

两套额外的括号似乎都是必要的。