如何将哈希与其他参数一起传递给perl中的子例程?

时间:2014-05-13 16:58:26

标签: perl hash subroutine

我的代码:

$self->commitToPerforce($network_name[0], {"size_of_table=>$row->{numRecords}"});

sub commitToPerforce {
    my $self = shift;
    my $network = shift;
    my %metadata = shift;

    open my $FH, ">$local_metadata_file" || die "Could not open file $local_metadata_file";
    print $FH Dumper(%metadata);
    close $FH;
}

问题是,这是进入文件的内容:

$VAR1 = 'HASH(0x320adf0)';
$VAR2 = undef;

不是我要找的东西。

还试过这个:

print $FH Dumper(\%metadata);

这只是给了我这个:

$VAR1 = {
      'HASH(0x223cea0)' => undef
    };

我想要哈希的内容。不是对哈希的引用。

现在越来越近了:

my $hash = {"size_of_table=>$row->{numRecords}"};
$self->commitToPerforce($network_name[0], $hash);

   open( my $FH, ">", $local_metadata_file ) || die "Could not open file $local_metadata_file";
print $FH Dumper($metadata);
close $FH;

结果:

 $VAR1 = {
      'size_of_table=>0' => undef
    };

' undef'

是什么?

哦。我现在看到了。我的哈希不应该只是一个字符串。

并且因为我没有其他地方可以抱怨:为什么花这么多时间以这种方式思考我的数据结构是个好主意?

2 个答案:

答案 0 :(得分:3)

以下是对您的代码的一些评论

  • 我希望调用commit_to_perforce与方法定义位于不同的文件中?

  • 通常更清楚地分别定义哈希参数然后传递对它的引用,而不是直接在参数列表中传递匿名哈希

  • 在方法中,通常最好shift $self关闭参数列表的值,然后为其余参数执行列表分配

    < / LI>
  • 您应该使用open的三参数形式,并使用包含die的{​​{1}}字符串检查其是否成功,以提供原因< / em>表示失败,或只是$!

    由于use autodie运算符的优先级,您的代码会检查字符串||的真实性,而不是">$local_metadata_file"的返回值。您可以使用低优先级open运算符,也可以将参数括号括起来or

  • 通常的做法是为全局标识符保留大写字母,例如包open。通常应使用小写字母,数字和下划线命名局部变量

考虑到所有这些因素,以下是您的代码的外观

Dumper

my %meta = (
  size_of_table => $row->{numRecords},
);

$self->commit_to_perforce($network_name[0], \%meta);

我希望这会有所帮助

答案 1 :(得分:1)

第一个问题:你正在传递一个对该函数的哈希引用(这是正确的方法),但是你要处理的是函数内的哈希值。

第二个问题:您显然没有启用use warnings,因为您应该收到此警告:

Odd number of elements in hash assignment at programname.pl line X

首先,请将use warnings;放在程序的顶部。

第三个问题:您的open存在错误,因为运营商优先,它永远不会失败。这句话:

open my $FH, ">$local_metadata_file" || die "Could not open file $local_metadata_file";

实际上是:

open my $FH, (">$local_metadata_file" || die "Could not open file $local_metadata_file");

因此">$local_metadata_file"将始终为true,并始终求值为该字符串,然后不检查open的返回码。当你了解它时,改为现代3-argument open。改为

open my $FH, ">", $local_metadata_file or die "Could not open file $local_metadata_file";

open( my $FH, ">", $local_metadata_file" ) || die "Could not open file $local_metadata_file";

全部翻到此功能:

sub commitToPerforce {
    my $self = shift;
    my $network = shift;
    my $metadata = shift; # Hash reference, not a hash.

    open my $FH, ">", $local_metadata_file or die "Could not open file $local_metadata_file";
    print $FH Dumper(%{$metadata});
    close $FH;
}

您还可以将散列引用传递给Dumper,它会将其视为散列,而不仅仅是一个扁平的键/值对列表,这就是传入散列时会发生的情况。

    print $FH Dumper($metadata);

了解参考资料。它们对于有效使用Perl至关重要。运行perldoc perlreftut以阅读Perl附带的教程。

修改

我刚注意到你做错了另一件事。这一行

{"size_of_table=>$row->{numRecords}"};

正在构建一个单元素哈希,其中包含一个键的字符串,没有值。你真正想要的是

{ size_of_table => $row->{numRecords} };

现在,您有一个单元素哈希,其中包含一个密钥size_of_table,该密钥引用$row->{numRecords}中的数字值,无论可能是什么。