我的代码:
$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'
是什么?哦。我现在看到了。我的哈希不应该只是一个字符串。
并且因为我没有其他地方可以抱怨:为什么花这么多时间以这种方式思考我的数据结构是个好主意?
答案 0 :(得分:3)
以下是对您的代码的一些评论
我希望调用到commit_to_perforce
与方法定义位于不同的文件中?
通常更清楚地分别定义哈希参数然后传递对它的引用,而不是直接在参数列表中传递匿名哈希
在方法中,通常最好shift
$self
关闭参数列表的值,然后为其余参数执行列表分配
您应该使用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}
中的数字值,无论可能是什么。