Perl参考子例程

时间:2016-10-14 00:22:09

标签: perl hash reference

我试图传递2个数组和对子程序的引用。它适用于阵列,但不适用于参考" $ plistref"。当我尝试在子程序中使用它时,就像我之前使用它一样,它不起作用。

...
    my $locPlist = "conf.plist";
    my $configdict = NSDictionary->dictionaryWithContentsOfFile_($locPlist);
    my $plistref   = Foundation::perlRefFromObjectRef($configdict);

    my @contentMatchs;
    foreach ( @{ $plistref->{content_match} } ) {
        push @contentMatchs, $_->{match};
    }

    ....

    # Process the files
    _moveFile(\@files, \@contentMatchs, \$plistref);
}

sub _moveFile {
    my ($files_ref, $contentMatchs_ref, $plistref_ref) = @_;

    my @files           = @{ $files_ref };
    my @contentMatchs   = @{ $contentMatchs_ref };
    my $plistref        = $plistref_ref;

    my @spools = @{ $plistref->{SPOOLS} };
....
}

它告诉我最后一行"不是HASH参考。" 我无法弄清楚如何通过子程序传递这个参考。

编辑:我尝试使用" shift"它工作了!它看起来不是最好的选择

    _moveFile($plistref, \@files, \@contentMatchs);
}

sub _moveFile {
    my $plistref        = shift;

    my ($files_ref, $contentMatchs_ref) = @_;
    my @files           = @{ $files_ref };
    my @contentMatchs   = @{ $contentMatchs_ref };

感谢您的帮助!

-Tim。

3 个答案:

答案 0 :(得分:3)

你的“解决方法”改变了一些事情。最初,你有这个:

_moveFile(\@files, \@contentMatchs, \$plistref);

而且,在子程序中,这个:

sub _moveFile {
  my ($files_ref, $contentMatchs_ref, $plistref_ref) = @_;

解决方法之后,请告诉我们:

_moveFile($plistref, \@files, \@contentMatchs);

而且,在子程序中,这个:

sub _moveFile {
  my $plistref        = shift;
  my ($files_ref, $contentMatchs_ref) = @_;

你说你“尝试使用shift解决方法并且它有效!”但问题不在于使用shift来解决问题。这是从传递\$plistref到传递$plistref的变化。

你显然已经认识到使用引用将数组和哈希传递给子程序是个好主意。这太好了。但你似乎没有注意到的是$plistref已经是一个引用,所以你不需要再次引用它。通过在原始代码中传递\$plistref,您传递对包含对哈希的引用的标量的引用。所以Perl告诉你它“不是HASH引用”是完全正确的。

因此,您可以回到原始代码的大部分内容,只需解决实际问题。

_moveFile(\@files, \@contentMatchs, $plistref);

而且,在子程序中,这个:

sub _moveFile {
  my ($files_ref, $contentMatchs_ref, $plistref_ref) = @_;

一切都会按你的意愿运作。 shift是一个完整的红鲱鱼。

答案 1 :(得分:2)

_moveFile(\@files, \@contentMatchs, \$plistref);在这里,您将对HASHREF的引用作为第三个参数传递。即,对HASH的引用的引用。你不需要传递HASHREF作为参考,因为它已经是一个。即,像这样调用你的子程序:_moveFile(\@files, \@contentMatchs, $plistref);

如果出于某种原因,您希望将引用传递给HASHREF,则可以取消引用这样的值:${$plistref}->{SPOOLS}

_moveFile($plistref, \@files, \@contentMatchs);在这里,在您的编辑中,您将HASHREF作为第一个参数传递。这就是使用my $plistref = shift的原因 - 该变量具有预期的引用级别。

答案 2 :(得分:0)

\$plistref是对标量的引用。要在函数中取消引用它,您需要说

my $plistref        = ${ $plistref_ref };