perl 子程序参数列表 - “通过别名传递”?

Posted

技术标签:

【中文标题】perl 子程序参数列表 - “通过别名传递”?【英文标题】:perl subroutine argument lists - "pass by alias"? 【发布时间】: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。 :( 【参考方案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:我添加了一个答案***.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

以上是关于perl 子程序参数列表 - “通过别名传递”?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Perl 中获取调用堆栈列表?

perl 函数的参数列表

perl - 帮助修改代码以包含子例程的使用

将参数传递给 Perl 子例程时,是不是会影响数据复制性能?

GWA2-Perl的面向对象方法中数组或哈希列表参数传递问题

Perl:关闭信号处理程序中的子进程管道挂起?