You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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'}
                      }
          }
        ];
解答

核心问题解析

  1. Data::Dumper的引用简化机制:你看到的$VAR1->[1]{'deal'}{'pid1'}并非错误,是Dumper的默认优化行为。因为store2的pid1对应的产品哈希和store1的pid1是同一个内存引用,Dumper为了避免重复打印相同内容,会用已输出的变量路径来指代重复的引用。

  2. 数组存储结构错误:当前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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 17:25:50