我包含的代码已经过验证,说明了我的问题。我的目标是从这里模拟的数据库查询返回的哈希值为%r(包含数字索引),并使用“name”字段的值作为接收哈希中的键。 (此哈希将包含多个查询的结果。)
我觉得我可能正在做一些愚蠢的引用和解除引用。我真的想尝试掌握这里的概念。谢谢!
#!/usr/bin/perl -T
use strict;
use warnings;
my %hash;
my %r = (
'1' => {
name => 'Harry',
desc => 'Prince',
},
);
MergeHash(\%hash,\%r);
foreach my $name (keys %hash) {
print "name = $name, desc = $hash{$name}{desc}\n"; # EDIT: REVISED
}
exit;
sub MergeHash {
my $h = shift; # reference to receiving hash
my $r = shift; # reference to giving hash
foreach my $i (keys %{$r}) {
$$h{name} = $$r{$i}{name} || 'Unknown'; # okay
$$h{name}{desc} = $$r{$i}{desc} || 'Unknown'; # Can't use string ("Harry") as a HASH ref while "strict refs" in use at ./test.pl line 25.
}
}
编辑:根据要求,输出(也在上面的代码中表示为注释):
Can't use string ("Harry") as a HASH ref while "strict refs" in use at ./test.pl line 25.
编辑#2:修改后的打印行(在上面的代码中),以清除%hash中所需的结构。
答案 0 :(得分:3)
$$h{name}{desc}
更明确地写为
$h->{name}{desc}
是
的缩写$h->{name}->{desc}
由于这更清楚,$h->{name}
的值被用作哈希引用(就像之前的$h
的值),但它包含一个字符串。
您只需要用实际名称替换name
,因为这就是您想要的密钥。
for my $i (keys(%$r)) {
$h->{ $r->{$i}{name} }{desc} = $r->{$i}{desc};
}
我们实际上并不需要$i
,所以让我们简化一下。
for my $row (values(%$r)) {
$h->{ $row->{name} }{desc} = $row->{desc};
}
上面的问题是它不适合每行多个字段。以下是更好的处理:
for my $row (values(%$r)) {
$h->{ $row->{name} } = {
desc => $row->{desc},
# ...
};
}
购买为什么可以在我们已经拥有的那个时创建一个新哈希?
for my $row (values(%$r)) {
$h->{ $row->{name} } = $row;
}
答案 1 :(得分:-2)
如果要使用给定哈希中的所有数据覆盖接收哈希的成员,则以下代码将起作用。
my %copyofh = %$h;
问题是$$ h假设$ h是对SCALAR的引用而它不是,它是对HASH的引用,你通常会看到人们在引用其成员时解除引用哈希,就像我所做的那样以上。另一种方法是声明这样的哈希副本,但这对你的用例不起作用:
class Order(models.Model):
# The relavant order fields which you require, i.e. order number etc.
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)