【问题标题】:perl subroutine argument lists - "pass by alias"?perl 子程序参数列表 - “通过别名传递”?
【发布时间】:2013-05-22 22:15:11
【问题描述】:

我只是难以置信地看着这个序列:

my $line;
$rc = getline($line); # read next line and store in $line

我一直都明白 Perl 参数是按值传递的,所以每当我需要传递一个大型结构或传递一个要更新的变量时,我都会传递一个 ref。

然而,阅读 perldoc 中的细则,我了解到 @_ 是由参数列表中提到的变量的别名组成的。读取下一位数据后,getline()返回$_[0] = $data;,直接存储$data $line

我喜欢这样 - 这就像在 C++ 中通过引用传递。但是,我还没有找到一种方法来为 $_[0] 分配一个更有意义的名称。有没有?

【问题讨论】:

  • 是的,Perl 总是通过引用传递
  • 好吧 - 不要与 Perl 引用混淆,Perl 引用更像 C 指针,因为它们必须被显式取消引用。
  • 不会 $arg = shift; $arg = $数据;做吗?或者“shift”会复制参数吗?编辑:我测试了传递的标量和'shift'ed参数的地址,结果表明shift确实会复制,因此如上所述分配给$arg不会按预期影响$line。 :(

标签: perl parameters arguments pass-by-reference subroutine


【解决方案1】:

@Steve 的代码版本允许多个不同的参数:

sub my_sub {
  SUB:
  for my $thisarg ( $_[0] ) {
    for my $thatarg ($_[1]) {
      code here sees $thisarg and $thatarg as aliases 
      last SUB;
    }
  }
}

当然,这会带来多级嵌套及其自身的代码可读性问题,因此仅在绝对必要时才使用它。

【讨论】:

    【解决方案2】:

    最简单的方法可能就是使用循环,因为循环将它们的参数别名为一个名称;即

    sub my_sub {
      for my $arg ( $_[0] ) {
        code here sees $arg as an alias for $_[0]
      }
    }
    

    【讨论】:

    • 是的,但不是我所追求的——理想情况下,我希望为每个 arg 赋予不同的名称。看起来 Joel 是这样做的,但正如他所说,它非常混乱。
    • @Chap:我添加了一个答案stackoverflow.com/a/17343595/8127,它允许为每个 arg 指定不同的名称,但这也有其自身的混乱。
    【解决方案3】:

    你可以,它不是很漂亮:

    use strict;
    use warnings;
    
    sub inc {
      # manipulate the local symbol table 
      # to refer to the alias by $name
      our $name; local *name = \$_[0];
    
      # $name is an alias to first argument
      $name++;
    }
    
    my $x = 1;
    inc($x);
    print $x; # 2
    

    【讨论】:

    • Data::Alias 提供了相当多的美化。
    • 另外,Method::Signatures 有一个alias trait
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 2013-07-26
    • 2015-06-03
    • 2021-04-03
    • 2013-09-08
    • 2021-03-09
    • 1970-01-01
    相关资源
    最近更新 更多