[英]Can't use string (“a,b,c”) as an ARRAY ref
我正在为自动定理证明者编写一些代码。 我想为用户实现一个选项,以便在cmd行上传递文件并使它以批处理模式运行。
这是解析文件并填充@clauses
数组的代码。
# batch mode
if ($ARGV[0]) {
my $filename = $ARGV[0];
open(IN, "<", $filename);
chomp(@clauses = <IN>);
$conclusion2 = $clauses[@clauses - 1];
# set sos as negated conclusion
$SOS[0][0] = $conclusion2;
# negate the negation to get the desired conclusion for later
@conclusion = split(undef, $conclusion2);
# look for a ~, remove it if you find it, add one if you don't
for (my $i = 0 ; $i < @conclusion ; $i++) {
# while you're at it.....
# get rid of spaces and anything that isn't a ~ or letter
$conclusion[$i] =~ s/( |[^A-Za-z~])//;
if ($conclusion[$i] eq '~') {
splice(@conclusion, $i, 1);
$i--;
$found = 1;
}
}
if (!$found) {
$conclusion = "~$conclusion2";
}
else {
$conclusion = join(undef, @conclusion);
}
# now break up each line and make @clauses 2d
for (my $a = 0 ; $a < @clauses ; $a++) {
my $str = $clauses[$a];
my @tmp = split(',', $str);
for (my $b = 0; $b < @tmp; $b++) {
$clauses[$a][$b] = $tmp[$b]; # ERROR HERE
}
}
# for(my $i=0; $i<@clauses;$i++)
# {
# print "$i";
# for(my $b=0; $b<=@{@clauses};$b++)
# {
# print "$clauses[$a][$b]";
# }
# print "\n";
# }
}
我输入的内容超出了我的实际需要,但麻烦的部分是当我尝试用逗号分隔文件的行并将数组变成二维时。
在行上,我已标记为我收到错误
Can't use string ("a,b,c") as an ARRAY ref while "strict refs" in use
输入文件是这样设置的
a,b,c
b,~c
~b
~a
这将证明a
必须为真
这很奇怪,因为在交互式部分的代码中,我几乎一字不漏地做着完全相同的事情,并且效果很好。
编辑我敢肯定,错误就在这行之内
$clauses[$a][$b] = $tmp[$b];
错误消息如下:
can't use string ("a,b,c") as ARRAY ref while strict refs in use.
我看不到我需要进行任何反引用,那么问题可能是什么呢?
实际上,您应该尽可能多地显示程序,因为很难看到未声明的变量的范围。
我可以向您保证,如果您已use warnings
,则split undef
会导致警告
Use of uninitialized value in regexp compilation
问题是您已经设定
$clauses[$a] = "a,b,c";
@tmp = ('a', 'b', 'c');
然后,您尝试做
$clauses[$a][$b] = $tmp[$b] for 0 .. 2
但是$clauses[$a]
是一个字符串 ,而不是数组引用。 和写作一样
"a,b,c"[$b] = $tmp[$b] for 0 .. 2
这没有任何意义。 因此错误消息Can't use string ("a,b,c") as an ARRAY ref
。
一个简单的解决方法是编写
$clauses[$a] = undef;
之后
my $str= $clauses[$a]
这样,数组元素现在是未定义的,并且在复制元素时,Perl可以在此处自动保存匿名数组。
但是,您的代码可能需要做更多的工作,因此,这里有一个版本可以满足我的要求。 我在末尾转储了@clauses
和$conclusion
的值以显示其内容
use strict;
use warnings;
my $conclusion;
my $conclusion2;
my @SOS;
if (@ARGV) {
my ($filename) = @ARGV;
open my $in_fh, '<', $filename or die qq{Unable to open "$filename" for input: $!};
chomp(my @clauses = <DATA>);
close $in_fh;
$conclusion2 = $clauses[-1];
$SOS[0][0] = $conclusion2;
$conclusion = $conclusion2;
$conclusion =~ tr/A-Za-z~//cd;
$conclusion = '~'.$conclusion unless $conclusion =~ tr/~//d;
$_ = [ split /,/ ] for @clauses;
print $conclusion, "\n";
use Data::Dump;
dd \@clauses;
}
输出
a
[["a", "b", "c"], ["b", "~c"], ["~b"], ["~a"]]
问题在于$clauses[$a]
是一个字符串,而不是arrayref,因此$clauses[$a][$b] = ...
确实没有意义。 (这意味着“将$clauses[$a]
引用的数组的元素$b
设置为...
”,但是$clauses[$a]
并不引用数组。)
要解决此问题,请更改以下内容:
my $str = $clauses[$a];
my @tmp = split(',', $str);
for (my $b = 0; $b < @tmp; $b++) {
$clauses[$a][$b] = $tmp[$b]; # ERROR
}
对此:
$clauses[$a] = [split /,/, $clauses[$a]];
以一套$clauses[$a]
与你想要的内容的数组引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.