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{...} = ... ;
如果你能公开完整的代码,我可以帮助解决这个问题。
我在使用 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{...} = ... ;
如果你能公开完整的代码,我可以帮助解决这个问题。