【发布时间】:2019-06-01 20:44:01
【问题描述】:
我想通过读取由 -> 分隔的多维数组中的值来创建嵌套哈希,例如
Array 1: key1->key2->key3->value
Array 2: key1->key2->value
Array 3: key1->value
当键具有值和子键时,例如key2 有值,另一个键 key3 也有错误“不是 HASH 引用”。似乎它正在覆盖以前的哈希并考虑它的数组。
感谢您的帮助。我尝试使用 dumper 模块调试和打印变量和输出的值,发现它是 ARRAY 引用而不是哈希。
为了重现,请创建 .txt 文件,例如从 1 到 3.txt 在任何文件夹中,并且在这些文件中具有以下内容 1.txt : /TEST-TAG = ABC->DEF->fma->GHI/ 2.txt:/*TEST -TAG = ABC->DEF->fma 3.txt:/*TEST-TAG = ABC->DEF 然后在perl脚本中
#!/usr/bin/perl
use strict;
use warnings;
my @lines=`grep -R 'TEST-TAG =' <FOLDER where .txt files present>`;
my $hash;
#parse the lines which has pattern /\*TEST-TAG = ABC->DEF->fma->GHI\*/
foreach (@lines)
{
print "line is $_\n";
my($all_cat) = $_ =~ /\=(.*)\*\//;
print "all cat is $all_cat\n";
my($testname) = $_ =~ /\/.*\/(.*)\./;
print "testname is $testname\n";
if (!$all_cat eq "") {
$all_cat =~ s/ //g;
my @ts = split(',', $all_cat);
print "ts is @ts\n";
my $i;
foreach (@ts) {
my @allfeat = split('->',$_);
my $count = scalar @allfeat;
for ($i = 0; $i<$count; $i++) {
my @temparr = @allfeat[$i..$count-1];
print "temparr is @temparr\n";
push @temparr, $testname;
ToNestedHash($hash, @temparr);
}
}
}
}
sub ToNestedHash {
my $ref = \shift;
print "sandeep in ref $ref\n";
print "sandeep in ref", ref($ref), "\n";
my $h = $$ref;
print "sandeep h $h\n";
my $value = pop;
print "sandeep value is $value\n";
print "sandeep array is @_\n";
print "refrence", ref($h), "\n";
foreach my $i (@_) {
print " before INDEX $i\n";
print Dumper($ref);
$ref =\$$ref->{ $i };
print "after INDEX $i\n";
print Dumper($ref);
}
if (!isinlist(\@{$$ref},$value)) {
push @{$$ref}, $value;
}
return $h;
}
# If element exists in the list
sub isinlist {
my ($aref, $key) = ($_[0], $_[1]);
foreach my $elem (@$aref){
if ($elem eq $key) {
return 1;
}
}
return 0;
}
我通过调试打印得到这个输出
line is File.txt:/*TEST-TAG = ABC->DEF->fma->GHI*/
all cat is ABC->DEF->fma->GHI
testname is hmma_884_row_row_f16_f16
ts is ABC->DEF->fma->GHI
temparr is ABC DEF fma GHI
sandeep in ref REF(0x12a1048)
sandeep in refREF
sandeep h HASH(0x12a09a0)
sandeep value is hmma_884_row_row_f16_f16
sandeep array is ABC DEF fma GHI
refrenceHASH
REF
temparr is DEF fma GHI
sandeep in ref REF(0x12a1048)
sandeep in refREF
sandeep h HASH(0x12a09a0)
sandeep value is hmma_884_row_row_f16_f16
sandeep array is DEF fma GHI
refrenceHASH
REF
temparr is fma GHI
sandeep in ref REF(0x12a1048)
sandeep in refREF
sandeep h HASH(0x12a09a0)
sandeep value is hmma_884_row_row_f16_f16
sandeep array is fma GHI
refrenceHASH
Not a HASH reference at createjson.pl line 80.
有问题的线路是$ref =\$$ref->{$_} foreach (@_);
【问题讨论】:
-
Global symbol "@lines" requires explicit package name (did you forget to declare "my @lines"?) at .code.tio line 6. -
它在我的代码中,但我没有在示例中添加它。现在添加它。
-
if (!$all_cat eq "")是一个奇怪的结构。当你实际上——以迂回的方式——测试真实性时,为什么要特意让它听起来好像你在测试空虚?!$all_cat首先被评估,给出一个真值,该值将被转换为一个字符串(“1”或“”,空字符串)用于字符串比较。如果你想要真实,更清楚地说if ($all_cat),如果你想要非空,更清楚地说if ($all_cat ne '')。 -
if (!$all_cat eq "")不只是故意混淆if (length $all_cat)的写法吗? -
另外,这里有很多非常令人困惑的参考语法。我不确定代码是由非常聪明的人编写的,还是没有他们想象的那么聪明的人编写的:-)