"Use of uninitialized value in scalar chomp" in Perl

11.9k Views Asked by At

I get the below error when i run the script: Could someone help me on this

Use of uninitialized value $user in scalar chomp at ./temp.pl line 38, <DATA> line 558.
Use of uninitialized value $modelName in scalar chomp at ./temp.pl line 39, <DATA> line 558.
Use of uninitialized value $Application in scalar chomp at ./temp.pl line 40, <DATA> line 558.
Use of uninitialized value $user in string eq at ./temp.pl line 42, <DATA> line 558.

The code is as below, could some-one help me on this:

my ($user) = $ARGV[0];
my ($modelName) = $ARGV[1];
my ($Application) = $ARGV[2];

chomp($user);
chomp($modelName);
chomp($Application);

if ( ($user eq "") || ($modelName eq "") || ($Application eq "")) {
  &usage;
}

sub usage {
  print "\tUsage : $0 User ModelName Application\n";
  exit (1);
}
2

There are 2 best solutions below

3
On BEST ANSWER

The program is expecting parameters - user, model name, and application - on the command line and you have provided none

There is no need to chomp a value passed from the command line as it will never end in a new line

Your code is better written like this

usage() unless @ARGV == 3;

my ($user, $modelName, $Application) = @ARGV;
1
On

You are suppose to input three parameters on the command line when you run your program. However, there is no check to see if you do so in your program. Thus, if there is no first parameter, $ARGV[0] is null, and so is $user. When you chomp user, you get an error. Here's a slightly modified version of your program:

use strict;
use warnings;

# Let's give some directions

my $usage <<USAGE;

    Usage: <program> <user> <model> <application>

    All parameters are required!

USAGE

if (scalar @ARGV != 3) {
   die "$usage";
}

my $user =        shift;
my $modelName =   shift;
my $Application = shift;

# No need for this

chomp $user;
chomp $modelName;
chomp $Application;

Notice a few things:

  • I have use strict and use warnings pragmas. Always use these in all of your programs. These help spot about 90% of errors that people make in programs.
  • I check whether the arguments are there before I do anything else. I use scalar to force @ARGV into giving me its scalar value (which it would do anyway in this context), and see if there are actually three and only three values in it. If there aren't three values, I give the usage text.
  • You don't need to chomp the command line parameters. Chomping is only really needed on file input because each file line is read in with its EOL character or characters. This is mainly done to ensure that the <...> doesn't return a zero if the line is merely blank. If the line is blank, you'll get <...> returning at least a single NL character.

One more thing...

I like to use a $usage text rather than a subroutine. I set the usage text right on the very top of my program where someone who looks at my code can see it, and read exactly how the program is used. I can also put my usage text in a die statement.

Plus, it's bad form to print anything out in a subroutine. Subroutines should return values which the calling program can operate on.