2013-08-22 104 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; 
    } 
}