我如何在opendir的方式中允许子例程参数中的词法变量声明?

时间:2016-02-07 14:41:36

标签: perl reference

一些Perl函数允许您传递参数列表中声明的词法变量:

opendir(my $h, '.') or die $!;

这到底发生了什么?我可以使用引用来模拟类似的行为:

sub a {
    my ($ref) = @_;
    $$ref = 100;
}

my $value;
a(\$value);
STDOUT->say($value); # => 100

但它不像opendir那样工作,因为我需要将标量包装在引用中:

a(my $value);
STDOUT->say($value); # => nothing

是否可以在此处重现opendir的行为?

2 个答案:

答案 0 :(得分:3)

根据perlsub

  

传入的任何参数都显示在数组@_中。因此,如果您使用两个参数调用函数,那么这些参数将存储在$_[0]$_[1]中。数组@_是一个本地数组,但其元素是实际标量参数的别名。特别是,如果更新元素$_[0],则更新相应的参数(如果不可更新,则会发生错误)。

换句话说,@_元素的分配将对呼叫的实际参数进行分配

sub a {
    $_[0] = 100;
}

my $x;
a($x);
print "$x\n"; # => 100

可替换地:

sub a {
    my $x = \$_[0];
    $$x = 100;
}

a(my $x);
print "$x\n"; # => 100

答案 1 :(得分:1)

这是一个可能有帮助的例子。请注意,它不会对打开模式进行任何检查,只是进行天真的猜测。如果您需要这样的东西,那么您应该在版本10.1或更高版本的Perl 5中use autodie

与您的问题相关的部分是该行

my ($mode, $file) = @_[1,2]

将第二个和第三个输入参数拉出以供本地使用。子例程打开传入的文件路径和模式以使用词法文件句柄打开文件,然后通过使用行分配第一个参数来返回该文件句柄

$_[0] = $fh;


use strict;
use warnings 'all';

my_open(my $fh, '<<', 'xyzzy');

sub my_open {

    my ($mode, $file) = @_[1,2]

    my $modestring = $mode =~ />>/ ? 'append' : $mode =~ />/ ? 'write' : 'read';

    open my $fh, $mode, $file or die qq{Unable to open "$file" for $modestring: $!};

    $_[0] = $fh;
}