Data::Dumper 包装第二个单词的输出

Data::Dumper wraps second word's output

我在使用 Data::Dumper 尝试检查将大量数据导入哈希时遇到了一个相当奇怪的问题。

我的数据在另一个文件中看起来像这样。

##Product ID => Market for product
ABC => Euro
XYZ => USA
PQR => India

然后在我的脚本中,我尝试将我的数据列表读入散列,如下所示:

open(CONFIG_DAT_H, "<", $config_data);       
while(my $line = <CONFIG_DAT_H>) {
    if($line !~ /^\#/) {
        chomp($line);
        my @words = split(/\s*\=\>\s/, $line);
        %product_names->{$words[0]} = $words[1];
    }
}
close(CONFIG_DAT_H);
print Dumper (%product_names);

我的解析大部分工作正常,我可以在散列中找到我的所有数据,但是当我使用 Data::Dumper 打印它时,它无法正确打印。这是我的输出。

$VAR1 = 'ABC';
';AR2 = 'Euro
$VAR3 = 'XYZ';
';AR4 = 'USA
$VAR5 = 'PQR';
';AR6 = 'India

有人知道 Dumper 为什么要打印 ';我的第二列数据中前两个字母的字符数?

代码中有一处不清楚:*product_names 是散列还是散列引用?

  • 如果是哈希,应该使用%product_names{key}语法,而不是%product_names->{key},并且需要传递对Data::Dumper的引用,所以Dumper(\%product_names).

  • 如果它是一个 hashref 那么它应该被标记为正确的印记,所以 $product_names->{key}Dumper($product_names}.

mob if your input has anything other than \n it need be cleaned up more explicitly, say with s/\s*$// per comment. See the answer by ikegami 所述。

我还想补充一点,可以通过松开 if 分支来简化循环

open my $config_dat_h, "<", $config_data  or die "Can't open $config_data: $!";

while (my $line = <$config_dat_h>) 
{
    next if $line =~ /^\#/;  # or /^\s*\#/ to account for possible spaces

    # ...
}

我已经改成词法文件句柄,推荐的做法有很多好处。我还添加了 open 的检查,它应该始终存在。

该文件使用 CR LF 作为行尾。通过在您的代码中添加以下内容,这一点将变得显而易见:

local $Data::Dumper::Useqq = 1;

您可以将文件转换为使用 unix 行结尾(就像您在 unix 系统上一样)。这可以使用 dos2unix 实用程序来实现。

dos2unix config.dat

或者,替换

chomp($line);

搭配更灵活

$line =~ s/\s+\z//;

  • 注意:%product_names->{$words[0]}没有意义。它恰好在旧版本的 Perl 中做你想做的事,但它在新版本中理所当然地抛出错误。 $product_names{$words[0]} 是访问散列元素值的正确语法。
  • 提示:您应该使用 print Dumper(\%product_names); 而不是 print Dumper(%product_names);
  • 提示:您可能还会发现 local $Data::Dumper::Sortkeys = 1; 有用。 Data::Dumper 有如此糟糕的默认值:(
  • 提示:使用 split(/\s*=>\s*/, $line, 2) 而不是 split(/\s*=>\s*/, $line) 将允许值包含 =>.
  • 提示:不要无缘无故地使用全局变量。使用 open(my $CONFIG_DAT_H, ...) 而不是 open(CONFIG_DAT_H, ...),并将 CONFIG_DAT_H 的其他实例替换为 $CONFIG_DAT_H
  • 提示:使用 next if $line =~ /^#/; 可以避免大量缩进。

嗯...这对我来说似乎是错误的,即使你使用的是 Perl6:

%product_names->{$words[0]} = $words[1];

我不太了解 Perl6,但在 Perl5 中,考虑到 %product_names 存在并被声明,参考应该如下所示:

$product_names{...} = ... ;

如果你能公开完整的代码,我可以帮助解决这个问题。