0

I'm new to perl so please bear with me.

I have script that is parsing a CSV file. To make things easier to debug I am using a state machine FSA::Rules (works great love it).

Every thing is going well only now I need to make my logs make sense, as part of this I need to record line numbers so my program looks some thing like this.

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 ++;
}

But I get the following error

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

Any one know why $line would not be initialized? Thanks.

7
  • This isn't the code that produces the error. You never call subroutine do, and you shouldn't name a subroutine the same as a reserved word as, for one thing, it's very awkward to call. Please show the code that fails. Do you declare my $line again inside sub do? Commented Feb 1, 2012 at 23:06
  • The $line variable is not initialized because the contents of $line do not match the supplied regular expression. Please post all your code after adding use strict; and use warnings; after the #! line (which should be the first line of the script). Commented Feb 1, 2012 at 23:15
  • 5
    @David: I'm sorry? Variables don't get uninitialized if they fail to match a regex. And a #! line isn't necessary or even desirable (although strict and warnings are!) Commented Feb 1, 2012 at 23:22
  • 1
    How do you check for end of file? If you don't, for some strange reason, that is probably your error. Commented Feb 1, 2012 at 23:33
  • 2
    #! lines are not required in Unix, except as an optional mechanism to run your script from the command line without having to specify "/usr/bin/perl" in front of it. Commented Feb 1, 2012 at 23:57

1 Answer 1

4

When you reach end of file, $line = <CSV> will assign the undefined value to $line. The usual idiom is to check whether the readline function (which is implicitly called by the <> operator) returned a good value or not before proceeding ...

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

but you with your sequence of calls, you are avoiding that check. Your current code also increments $lineCount even when <CSV> does not return a good value, which may not be what you want either.

Sign up to request clarification or add additional context in comments.

1 Comment

You should mention that when written as you have it, perl's optimizer will rewrite the while loop into while (defined(my $line = <CSV>)) {...} which is where the defined test comes from, since a while loop would normally only test for a true value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.