Perl遍历哈希得到异常结果,附示例脚本求助
问题
我正在重新维护多年前开发的Perl应用,需重建部分模块,但如今在哈希处理上遇到问题。我编写了一段遍历哈希的测试脚本,不理解为何最后一次循环输出'pid1' => $VAR1->[1]{'deal'}{'pid1'},而非预期的产品数据哈希。请问我哪里出错了?
测试脚本
#!usr/bin/perl use strict; use warnings; use Data::Dumper qw(Dumper); my %stores; push @{$stores{'store1'}}, 'pid1'; push @{$stores{'store1'}}, 'pid2'; push @{$stores{'store2'}}, 'pid1'; print Dumper(\%stores); my %products = ( 'pid1' => { 'name' => 'Product 1', 'color' => 'red' }, 'pid2' => { 'name' => 'Product 2', 'color' => 'blue' } ); print Dumper \%products; my @offers; foreach my $storeid (keys %stores) { foreach my $pid (@{$stores{$storeid}}) { my %offer; $offer{$storeid}{'deal'}{$pid} = $products{$pid}; push(@offers, %offer); } } print Dumper(\@offers);
输出结果
$VAR1 = { 'store1' => [ 'pid1', 'pid2' ], 'store2' => [ 'pid1' ] }; $VAR1 = { 'pid2' => { 'name' => 'Product 2', 'color' => 'blue' }, 'pid1' => { 'color' => 'red', 'name' => 'Product 1' } }; $VAR1 = [ 'store1', { 'deal' => { 'pid1' => { 'color' => 'red', 'name' => 'Product 1' } } }, 'store1', { 'deal' => { 'pid2' => { 'name' => 'Product 2', 'color' => 'blue' } } }, 'store2', { 'deal' => { 'pid1' => $VAR1->[1]{'deal'}{'pid1'} } } ];
解答
核心问题解析
Data::Dumper的引用简化机制:你看到的
$VAR1->[1]{'deal'}{'pid1'}并非错误,是Dumper的默认优化行为。因为store2的pid1对应的产品哈希和store1的pid1是同一个内存引用,Dumper为了避免重复打印相同内容,会用已输出的变量路径来指代重复的引用。数组存储结构错误:当前
push(@offers, %offer)会把哈希展开成键值对列表(storeid字符串 + 哈希引用)存入数组,导致@offers的结构是交替的字符串和哈希,这不符合常规的结构化数据存储需求。
修正步骤
1. 修正数组存储结构
如果希望@offers的每个元素是独立的店铺deal哈希,应该推入哈希的引用而非展开哈希:
my @offers; foreach my $storeid (keys %stores) { foreach my $pid (@{$stores{$storeid}}) { my %offer; $offer{$storeid}{'deal'}{$pid} = $products{$pid}; push(@offers, \%offer); # 推入哈希引用 } }
2. 让Dumper完整打印所有内容
如果想强制Dumper重复打印相同的引用内容,关闭其引用简化功能,只需添加一行设置:
use Data::Dumper qw(Dumper); $Data::Dumper::Deepcopy = 1; # 启用深度复制,禁用引用简化
修正后输出示例
启用$Data::Dumper::Deepcopy = 1后的输出会完整展示所有哈希内容:
$VAR1 = [ { 'store1' => { 'deal' => { 'pid1' => { 'color' => 'red', 'name' => 'Product 1' } } } }, { 'store1' => { 'deal' => { 'pid2' => { 'name' => 'Product 2', 'color' => 'blue' } } } }, { 'store2' => { 'deal' => { 'pid1' => { 'color' => 'red', 'name' => 'Product 1' } } } } ];
内容的提问来源于stack exchange,提问作者Niska
相关产品推荐
相关产品推荐

