skip to Main Content

I am hoping you may be able to help me with a problematic script I am running as part of some quality control checks on a genetic analyses dataset I am running.

When I run the script, which is a PERL script (run in Windows), I get the following error:

Use of uninitialized value $_ in pattern match (m//) at /IC/ic.pl line 803, <$z> line 1.

Looking at the ic.pl file, line 803 that seems to be generating the error is the following line: if (/^##/)
in the following part of the script:

my $header = <$z>;
if ($header =~ /^#.*/) {
    my $loop = 1;
    while ($loop) {
        if (/^##/) {  }
        else {
            $header = <$z>;
            $loop = 0;
        }
    }
}
chomp $header;

I am an absolute novice at coding and scripts, so I am not sure what the problem is. If anyone is able to shed some light on potential causes I would be so grateful.

Thank you!

I have tried to run the same script via the Windows Subsystem for Linux/Ubuntu, and I receive the same error.

2

Answers


  1. Your error means that the $_ variable is undefined, it does not contain a value. Typically this would happen because the file handle is exhausted, or was never opened, or the file is empty.

    In your case it probably happens because you tried to invent your own loop control, and it does not check for eof (end of file).

    Typically, you never run into this problem, because it is idiomatic to use something like this to read a file:

    while (<$fd>) {
        ....
    }
    

    This construct will not yield any undefined values, since that will end the loop.

    If you do want to end the loop before it reaches eof, you can use last:

    while (<$fd>) {
        if (! /^##/ ) {
            $header = <$fd>;
            last;              # exit loop
        }
    }
    
    Login or Signup to reply.
  2. if (/^##/) {  }
    

    is short for

    if ($_ =~ /^##/) {  }
    

    But you don’t set $_. That line is probably supposed to be

    if ($header =~ /^##/) {  }
    

    Full code:

    my $header = <$z>;
    if ($header =~ /^#.*/) {
        my $loop = 1;
        while ($loop) {
            if ($header =~ /^##/) {  }
            else {
                $header = <$z>;
                $loop = 0;
            }
        }
    }
    
    chomp $header;
    

    There are some problems with that. I think you meant to place the $header = <$z> in the "then" part of the if statement. Fixed (and simplified):

    my $header = <$z>;
    $header = <$z> while $header =~ /^##/;
    
    chomp $header;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search