user3477363
user3477363

Reputation: 11

How to distinguish between "0" and NULL in perl?

Here we are looking for the string "reftext" in the given file. The line next to this contains a string with 3 integers. So we are extracting them in @all_num. We are printing the value of @all_num[2] only if is not NULL. But the logic used here doesn't print @all_num[2] even if it has 0.

#!/usr/bin/perl
open( READFILE, "<myfile.txt" );
@list        = <READFILE>;
$total_lines = scalar @list;

for ( $count = 0; $count < $total_lines; $count++ ) {
    if (@list[ $count =~ /reftext/ )
        {
            @all_num = @list[ $count + 1 ] =~ /(\d+)/g;
            if ( @all_num[2] != NULL ) {
                print "@all_num[2]\n";
            }
    }
}

Upvotes: 1

Views: 6766

Answers (5)

redolent
redolent

Reputation: 4259

If the other answers do not work, try treating the variable as a string:

if ( $all_num[2] == 'null' && length($all_num[2]) == 4 ){
     # null
} else {
     # not null
}

As with any code you write, be sure to test your code.

Upvotes: 0

Borodin
Borodin

Reputation: 126722

This is how your program would look using best practices

You should

  • Always use strict and use warnings, and declare all your variables with my

  • Use the three-parameter form of open

  • Check that open calls succeeded, and include $! in the die string if not

  • Use a while loop to process a file one line at a time, in preference to reading the entire file into memory

#!/usr/bin/perl

use strict;
use warnings;

open my $fh, '<', 'myfile.txt' or die $!;
while ( <$fh> ) {

  next unless /reftext/;

  my $next_line = <$fh>;
  my @all_num = $next_line =~ /\d+/g;
  print "$all_num[2]\n" if defined $all_num[2];
}

Upvotes: 2

Dave Sherohman
Dave Sherohman

Reputation: 46187

Perl does not include a NULL, so the line

if(@all_num[2]!= NULL)

is nonsensical in Perl. (More accurately, it attempts to locate a sub named NULL and run it to get the value to compare against @all_num[2], but fails to do so because you (presumably) haven't defined such a sub.) Note that, if you had enabled use strict, this would cause a fatal error instead of pretending to work. This is one of the many reasons to always use strict.

Side note: When you pull a value out of an array, it's only a single value, so you should say $all_num[2] rather than @all_num[2] when referring to the third element of the array @all_num. (Yes, this is a little confusing to get used to. I hear that it's been changed in Perl 6, but I'm assuming you're using Perl 5 here.) Note that, if you had enabled use warnings, it would have told you that "Scalar value @all_num[2] better written as $all_num[2]". This is one of the many reasons to always use warnings.

If you want to test whether $all_num[2] contains a value, the proper way to express that in Perl is

if (defined $all_num[2])

Upvotes: 4

mpapec
mpapec

Reputation: 50647

Hope this helps,

use strict;
use warnings;

my @fvals = (
 [ i => undef ],
 [ j => 0 ],
 [ k => "" ],
);

for my $r (@fvals) {
  my ($k, $v) = @$r;
  if    (!defined($v)) { print "$k is undef\n"; }
  elsif (!length($v))  { print "$k is empty string\n"; }
  # elsif (!$v)        { print "$k is zero\n"; }
  # recognizes zero value in "0.0" or "0E0" notation
  elsif ($v == 0)      { print "$k is zero\n"; }
}

output

i is undef
j is zero
k is empty string

Upvotes: 5

serenesat
serenesat

Reputation: 4709

Try this:

#!/usr/bin/perl
use warnings;
use strict;

open(READFILE, "<", "myfile.txt") or die $!;
my @list = <READFILE>;
my $total_lines = scalar @list;
close (READFILE);

for(my $count=0; $count<$total_lines; $count++)
{
    if($list[$count] =~ /reftext/)
    {
        my @all_num = $list[$count+1] =~ /(\d+)/g;
        if($all_num[2] ne '')
        {
            print "$all_num[2]\n";
        }
    }
}

To check a variable is null or not:

if ($str ne '')
{
    print $str;
}

or better:

my ($str);
$str = "";
if (defined($str))
{
    print "defined";
}
else
{
    print "not defined";
}

Upvotes: 0

Related Questions