2012-02-01 151 views
0

我是Perl新手,请耐心等待。Perl未初始化的全局变量

我有解析CSV文件的脚本。为了让事情更容易调试,我正在使用状态机FSA :: Rules(非常喜欢它)。

现在每件事情都很顺利我需要让自己的日志变得有意义,因为我需要记录行号,所以我的程序看起来像这样。

my $line = ''; 
my $lineCount = 0; 
sub do { 
    ... 
    #CSV opened 
    ... 
    #State machine stuff happens here 
    readLine; 
    if ($line =~ m/.*Pattern*/){ 
     #do stuff 
    } 
} 
sub readLine{ 
    $line = <CSV>; 
    $lineCount ++; 
} 

但我得到以下错误

Use of uninitialized value $line in pattern match (m//) at 

任何一个知道为什么$线将不会被初始化? 谢谢。

+0

这不是产生错误的代码。你永远不会调用子程序'do',而且你不应该把一个子程序命名为一个保留字,因为一方面,调用非常尴尬。请显示失败的代码。你在'sub do'里面再次声明'我的$ line'吗? – Borodin 2012-02-01 23:06:19

+0

$ line变量未被初始化,因为$ line的内容与提供的正则表达式不匹配。请在#后添加'use strict;'和'use warnings'后发布所有代码!行(这应该是脚本的第一行)。 – 2012-02-01 23:15:30

+5

@大卫:对不起?如果变量不匹配正则表达式,变量不会被初始化。并且'#!'行不是必需的,甚至不需要(尽管严格和警告是!) – Borodin 2012-02-01 23:22:47

回答

4

当您到达文件末尾时,$line = <CSV>会将未定义的值分配给$line。通常的成语是检查readline的功能(这是隐含在<>操作者的称呼)是否返回一个很好的价值或没有继续之前...

while (my $line = <CSV>) { 
    # guaranteed that $line has a defined value 
    ... 
} 

,但你与你通话的顺序,你避免检查。即使当<CSV>没有返回一个好的值时,您的当前代码也会增加$lineCount,这可能不是您想要的值。

+2

你应该提到,当你有它的时候,perl的优化器会把while循环改写成'while(defined(my $ line = )){...}'这是定义的测试来自哪里,循环通常只会测试一个真实值。 – 2012-02-02 01:16:01