2

我在 Perl 中遇到了一些有趣的行为,希望能有所启发。如您所见,我创建了一个名为的数组,该数组@tuple具有两个数组引用。当我将它分配给一个键并提取它时,我只得到与引用相对的第一个数组 VALUE。谁能告诉我为什么会这样?

my @VMstoreName = ($storeName[$i]);
my @VMdiskCap   = ($diskCap[$i]);
print "VMstoreName : ". join(' ', @VMstoreName) . "\n";
print "VMdiskCap : ". join(' ', @VMdiskCap) . "\n";
# Initializing our key
my @tuple =  (\@VMstoreName, \@VMdiskCap);
print "After tuple " . join(' ', @tuple) . "\n";

@virtualMachines{$vmNames[$i]} = @tuple;
my @DEBUG = @{$virtualMachines{$vmNames[$i]}};
print "After first map : " . join(' ', @DEBUG) . "\n";
print "WHAT??? $DEBUG[0] $DEBUG[1]!!!\n";

这是输出,我希望 After first map 读取完全像 After tuple

VMstoreName : 172.16.1.3:/export/Paul/test-0
VMdiskCap : 1   
After tuple ARRAY(0x2c4ccf0) ARRAY(0x2c4cd38)
After first map 172.16.1.3:/export/Paul/test-0
WHAT??? 172.16.1.3:/export/Paul/test-0 !!!
4

4 回答 4

7

你的问题从这里开始(我猜):

 @virtualMachines{$vmNames[$i]} = @tuple;

@hash{...}是一个散列片:它一次访问散列中的多个条目(这可能只有一个条目)。作为 LHS 值的切片强加了列表上下文。

我们为这个列表分配 的值@tuple

现在列表赋值具有忘记多余值的属性:

my ($x, $y) = (1, 2, 3); # nobody likes № 3

所以上面的说法是一样的

$virtualMachines{ $vmNames[$i] } = $tuple[0];

%virtualMachines具体来说,这会为条目分配一个数组引用,因为@tuple它只保存 arrayrefs。

在下一行,您可以通过 访问此条目$virtualMachines{$vmNames[$i]}。这将评估为数组引用。然后,您将其取消引用到带有@{ ... }.

这将该数组的所有值分配给@DEBUG,而不是数组引用。如您的调试语句所示,这是 VMstoreName。

解决方案

将 arrayref 分配给%virtualMachines条目:

$virtualMachines{ $vmNames[$i] } = \@tuple;

数组和哈希只能保存标量,所以我们不能使用数组作为值,只能使用数组引用

于 2013-06-14T21:05:54.987 回答
3

您正在使用相同的键在列表上下文中分配给您的哈希。键在哈希中必须是唯一的,因此只有一个引用存储在您的哈希中。Hash-slice 只有 1 个元素宽,所以第二个引用会被忽略。

您应该使用标量上下文分配一个引用:@tuple

$virtualMachines{$vmNames[$i]} = \@tuple;
于 2013-06-14T21:07:12.470 回答
-2

初始化时传递对数组的引用@tuple。相反,只需传递数组:

my @tuple = (@VMstoreName, @VMdiskCap);
于 2013-06-14T21:05:46.637 回答
-2

它看起来像@tuple一个数组引用数组。您必须尊重每个元素才能按照您想要的方式打印它们。

my @tuple =  (\@VMstoreName, \@VMdiskCap);
print "After tuple " . join(' ', map { @$_ } @tuple) . "\n";
于 2013-06-14T21:08:16.873 回答