Ad8*_*891 1 perl hash subroutine perl-hash
我们试图将多个散列与一堆标量一起作为参数传递给子程序。问题在于这个子程序的多次调用,(如果我们在函数内部检索到两个哈希值后打印它们),只有其中一个(第一个)获得了正确的值。第二个是空的。我们尝试了很多东西-
1 ) 两个单独的散列,具有来自 Stackoverflow/PerlMonks 等的不同语法,并作为参考传递。
&mySub(\%hash0, \%hash1, $var0, $var1, $var2);
sub mySub{
my (%hash0, %hash1, $var0, $var1, $var2) = (@_);
}
Run Code Online (Sandbox Code Playgroud)
或者
&mySub(\%hash0, \%hash1, $var0, $var1, $var2);
sub mySub{
my %hash0 = %{$_[0]};
my %hash1 = %{$_[1]};
my $var0 = $[2]; my $var1 = $[3]; my $var3 = $[4];
}
Run Code Online (Sandbox Code Playgroud)
2)创建两个散列的数组并通过
my @joined_arr = (\%hash0, \%hash1);
&mySub (\@joined_arr, $var0, $var1, $var2);
sub mySub{
my (@joined_arr, $var0, $var1, $var2) = (@_);
my %hash0 = %{joined_arr[0]};
my %hash1 = %{joined_arr[1]};
# rest of the variables.
}
Run Code Online (Sandbox Code Playgroud)
4)创建散列的散列并通过
my %joined_hash;
%joined_hash{"first_one"} = %hash0;
%joined_hash{"second_one"} = %hash1;
&mySub (\%joined_hash, $var0, $var1, $var2);
sub mySub{
my %joined_hash, %hash0, %hash1;
%joined_hash = %{$_[0]};
%hash0 = %joined_hash{"first_one"};
%hash1 = %joined_arr{"second_one"};
# rest of the variables.
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,这还没有成功。如果有人有想法并喜欢分享,那将是非常有帮助的。
按照@zdim 和@Polar Bear 的建议,我尝试了这些东西->
将@_ 卸载到函数内部的标量的语法 ->
一种)
my ($ref_to_hash0, $ref_to_hash1, $var0, $var1, $var2) = @_;
b)
$ref_to_hash0 = shift;
$ref_to_hash1 = shift;
$var0 = shift;
$var1 = shift;
$var2 = shift;
Run Code Online (Sandbox Code Playgroud)
我也尝试过这 3 种散列引用的散列分配样式。
一种)
my %local_hash_shallow_copy = %$ref_to_hash0;
b)
my $local_hashref_deep_copy = dclone $ref_to_hash0;
C)
my %local_hash_shallow_copy = %{$ref_to_hash0};
似乎在这个 sub 调用的 9 次迭代中,我在 sub 中获得了正确的哈希值 2 次。在其他时候,我只是得到一个指针转储 -
$VAR1 = {
'HASH(0x1e32cc8)' => undef
};
Run Code Online (Sandbox Code Playgroud)
我正在使用 Dumper 在外部转储散列 - 就在 sub 调用之前,就在内部 - 就在我将值从 ref 转移到实际散列之后。这应该避免任何愚蠢的错误。
要么我在这里犯了一个非常基本的错误,要么遇到了一个不可思议的问题。正在调试。
供参考。
Perl 中的函数调用将标量列表作为参数传递,这就是您正确执行的操作。该函数接收 中的标量列表@_
,它们是这些参数的别名。
所以随着电话†
mySub(\%hash0, \%hash1, $var0, $var1, $var2);
Run Code Online (Sandbox Code Playgroud)
该函数有@_
五个标量,前两个是感兴趣的散列引用。
但是现在您将它们分配给哈希!
sub mySub{
my (%hash0, %hash1, $var0, $var1, $var2) = (@_); # WRONG
}
Run Code Online (Sandbox Code Playgroud)
使%hash0
填充了一切的@_
,如
%hash = (\%hash0 => \%hash1, $var0 => $var1, $var2 => undef);
Run Code Online (Sandbox Code Playgroud)
因为连续的标量被分配为键值对。列表中以 开头的其余变量%hash1
也作为该子例程中的词法符号引入,并且是undef
。
如果参数数量确实是奇数,您应该收到警告。(use warnings;
你的程序顶部有一行,对吗?)
需要将元素分配@_
给合适的标量,例如
sub mySub{
my ($ref_to_hash0, $ref_to_hash1, $var0, $var1, $var2) = @_;
}
Run Code Online (Sandbox Code Playgroud)
现在你有两个选择如何使用它
直接使用参考文献,$ref_to_hash0
。喜欢
foreach my $key (keys %$ref_to_hash0) {
$ref_to_hash0->{$key} ...
}
Run Code Online (Sandbox Code Playgroud)
简而言之,这是
高效,因为您不复制数据
它可能效率低下,因为每次访问都需要取消引用
它允许您通过写入来更改调用者中的数据 $ref_to_hash0
$ref_to_hash0->{some_key} = 'value'; # changes data IN THE CALLER
Run Code Online (Sandbox Code Playgroud)
这可能很方便,也可能很危险(因为它可能被错误地完成)
制作调用者数据的本地副本并使用它。请注意,这可能会有一些问题,因为您可能需要一个深层副本
use Storable qw(dclone); # may be needed
sub mySub{
my ($ref_to_hash0, $refhash1, $var0, $var1, $var2) = @_;
# If the caller's %hash0 has no references for values just dereference
# Tricky though -- what when the calling hash changes in the future?
my %local_hash_shallow_copy = %$ref_to_hash0;
# If the caller's %hash0 is a complex data structure, need a deep copy
my $local_hashref_deep_copy = dclone $ref_to_hash0;
# Changes to local hash/hashref do not affect data in the caller
}
Run Code Online (Sandbox Code Playgroud)
†通常不需要&
在问题中的名称前面使用,此处省略,除非您打算在调用中隐藏其原型。
归档时间: |
|
查看次数: |
109 次 |
最近记录: |