繁体   English   中英

不能使用字符串(“ a,b,c”)作为数组引用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM