11

在我的工作中,我在代码库中遇到了许多 Perl 脚本。其中一些包含具有以下语法奇怪的子例程:

sub sum($$$) {
    my($a,$b,$m)=@_;
    for my $i (0..$m) {
        $$a[$i] += $$b[$i] if $$b[$i] > 0;
    }
}

sub gNode($$;$$) {
    my($n,$l,$s,$d) = @_;
    return (
            "Node name='$n' label='$l' descr='$d'" ,
            $s ? ("Shape type='$s' /") : (),
            '/Node'
        );
}

sub gOut($$@) {
    my $h = shift;
    my $i = shift;
    if ($i > 0) {
        print $h (('')x$i, map '<'.$_.'>', @_);
    } else {
        print $h map '<'.$_.'>', @_;
    }
}

撇开这些子例程的用途不谈(我自己也不完全确定……),“参数列表”位置中的字符序列是什么意思?即。$$$这些示例中的$$;$$$$@序列。

我对 Perl 的了解非常有限,但我相信my($a,$b,$m)=@_;第一个示例 ( sum) 中的行将传递给子例程的参数解包到$a,$b$m局部变量中。这表明$$$表示 arity 和类型签名sum(在这种情况下,它需要三个标量)。这可能表明gOut需要两个标量和一个数组。这是正确的解释吗?

即使上述解释是正确的,我也不知道第二个例程(gNode)中分号的含义。

4

2 回答 2

16

请参阅Prototypes上的perldoc perlsub条目。

 # Declared as            Called as
 sub mylink ($$)        mylink $old, $new
 sub myvec ($$$)        myvec $var, $offset, 1
 sub myindex ($$;$)     myindex &getstring, "substr"
 sub mysyswrite ($$$;$) mysyswrite $buf, 0, length($buf) - $off, $off
 sub myreverse (@)      myreverse $a, $b, $c
 sub myjoin ($@)        myjoin ":", $a, $b, $c
 sub mypop (+)          mypop @array
 sub mysplice (+$$@)    mysplice @array, 0, 2, @pushme
 sub mykeys (+)         mykeys %{$hashref}
 sub myopen (*;$)       myopen HANDLE, $name
 sub mypipe (**)        mypipe READHANDLE, WRITEHANDLE
 sub mygrep (&@)        mygrep { /foo/ } $a, $b, $c
 sub myrand (;$)        myrand 42
 sub mytime ()          mytime

不要忘记:当然,这一切都非常强大,只能适度使用,以使世界变得更美好。

于 2013-08-02T00:40:57.250 回答
0

我同意其余的:除非您知道自己在做什么,否则不要使用子原型。“拥有权利的同时也被赋予了重大的责任。” 这些看起来像是由习惯于 C 原型的人创建的。例如,子sum真的应该有这个原型:

sub sum (\$\$\$) {
于 2013-08-02T12:55:56.153 回答