2013-08-22 93 views
1

这是怎么回事?我创建了一个简单的程序来读取行并在文件输出上打印。但它抛出了一些错误......Perl - 未初始化的变量

下面的代码和它的解释是对的评论:

use warnings; 
use List::MoreUtils qw(indexes); 

my @array_words =(); 
my @array_split =(); 
my @array_of_zeros = (0); 
my $index = 0; 

open my $info, 'models/busquedas.csv'; 
open my $model, '>>models/model.txt'; 

#First while is to count the words and store it into an array 
while(my $line = <$info>) { 
    @array_split = regex($line); 
    for (my $i=0; $i < scalar(@array_split); $i++) { 
      # Get the index if the word is repeated 
     $index = indexes { $_ eq $array_split[$i] } $array_words[$i]; 
      # if the word is not repeated then save it to the array by 
      # checking the index 
     if ($index != -1){ push(@array_words, $array_split[$i]); } 
    } 
} 

print $model @array_words; 

sub regex{ 
    # get only basic info like: 'texto judicial madrid' instead of the full url 
    if ($_[0] =~ m/textolibre=/ and 
     $. < 3521239 && 
     $_[0] =~ m/textolibre=(.*?)&translated/) { 
     return split(/\+/, $_[0]); 
    } 
} 

而且我不明白的错误是:

Use of uninitialized value $index in numeric ne (!=) at classifier.pl line 21, <$info> line 12216. 
Use of uninitialized value $index in numeric ne (!=) at classifier.pl line 21, <$info> line 12216. 
Use of uninitialized value $index in numeric ne (!=) at classifier.pl line 21, <$info> line 12216. 
Use of uninitialized value $index in numeric ne (!=) at classifier.pl line 21, <$info> line 12217. 
Use of uninitialized value $index in numeric ne (!=) at classifier.pl line 21, <$info> line 12217. 
Use of uninitialized value $index in numeric ne (!=) at classifier.pl line 21, <$info> line 12217. 
Use of uninitialized value $index in numeric ne (!=) at classifier.pl line 21, <$info> line 12217. 
Use of uninitialized value $index in numeric ne (!=) at classifier.pl line 21, <$info> line 12217. 
Use of uninitialized value $index in numeric ne (!=) at classifier.pl line 21, <$info> line 12218. 
Use of uninitialized value $index in numeric ne (!=) at classifier.pl line 21, <$info> line 12218. 

为什么未初始化$index?我已经声明并用0值初始化它! 我该如何解决这个问题?

+0

我想你已经误解了'索引'函数的工作原理。它应该有一个迭代列表,而不是单个元素。它返回索引,并且您已经拥有该项目的索引:'$ i'。 – TLP

+0

为什么在'@ array_words'的单个元素上调用'indexes'而不是整个数组? – nwellnhof

+0

但是我怎么能在其他语言上使用.indexof()函数呢? @nwellnhof –

回答

1

你初始化变量为零,但随后你

$index = indexes { $_ eq $array_split[$i] } $array_words[$i]; 

的功能可能会返回一个民主基金(因为$array_words[$i]不均衡$array_split[$i])更改它的值。否则它会返回一个,因为列表中只有一个元素。

顺便说一句,如果你不需要循环外的值,那么初始化一个循环外的变量是一种不好的做法。您可以在与indexes一起填充它的同一行声明my $index

+0

'索引'返回块评估为真的列表索引。如果它在这样的标量上下文中被(不正确地)使用,那么结果将是* last *这样的索引,或者如果列表中的元素没有满足该标准,则结果为“undef”。它将*永远* *“返回一个”*除非列表的第二个*元素是最后一个通过测试。 – Borodin

+0

@Borodin:真的吗? 'perl -MList :: MoreUtils = indexes -E'$ x = indexes {$ _ lt“c”} qw/cbdea /;说$ x''返回'2',但返回的索引是1和4。 – choroba

+0

在我的系统上给我'4'。你的'List :: MoreUtils'是最新的吗?运行'perl -MList :: MoreUtils -E'说$ List :: MoreUtils :: VERSION''最新版本是0.33。 – Borodin

0

正如所观察到的,indexes子程序不能像那样工作。它返回一个列表该块的评估值为true。像这样在标量上下文中使用它是错误的。

如果您要为此使用一个库,您需要any - 也从List::MoreUtils。该代码看起来像这样

while(my $line = <$info>) { 
    @array_split = regex($line); 
    for my $word (@array_split) { 
     push @array_words, $word unless any { $_ eq $word } @array_words; 
    } 
} 

但是,我认为你想要的东西更简单。根据我对你的代码的理解,Perl哈希将完成你所需要的。

我重构了你的程序。我希望它有帮助。

实质上,如果行中的每个“单词”不在散列中,它们将被推送到@array_words上。

您的regex子例程中似乎也有一个错误。声明

return split(/\+/, $_[0]); 

拆分全线并返回结果。我认为应该分拆只是你刚才提取的URL的查询部分,这样

return split /\+/, $1; 

按说你应该检查,看看open通话成功。添加autodie编译指示对你来说是隐含的。

use strict; 
use warnings; 
use autodie; 

open my $info, '<', 'models/busquedas.csv'; 
open my $model, '>>', 'models/model.txt'; 

my %unique_words; 
my @array_words; 

#First while is to count the words and store it into an array 
while(my $line = <$info>) { 
    for my $word (regex($line)) { 
    push @array_words, $word unless $unique_words{$word}++; 
    } 
} 

print $model "$_\n" for @array_words; 

sub regex { 

    my ($line) = @_; 

    # get only basic info like: 'texto judicial madrid' instead of the full url 
    return unless $line =~ /textolibre=/ and $. < 3521239; 
    if ($line =~ /textolibre=(.*?)&translated/) { 
    return split /\+/, $1; 
    } 
}