简体   繁体   中英

In Perl, how do I check for an undefined OR blank parameter?

I have some code like the following:

if (not defined $id) {
    print "Enter ID number: ";
    chomp ($id = <STDIN>);
    exit 0 if ($id eq ""); # If empty string, exit.
}
if (not defined $name) {
    print "Enter name: ";
    chomp ($name = <STDIN>);
    exit 0 if ($name eq ""); # If empty string, exit.
}
if (not defined $class) {
    print "Enter class: ";
    chomp ($class = <STDIN>);
    exit 0 if ($class eq ""); # If empty string, exit.
}

I'd like to be able to potentially pass only some of them (eg, name and class, but not ID), passing blanks for the unpassed ones, so I thought the following would work:

if (not defined $id || $id eq "") {
    print "Enter ID number: ";
    chomp ($id = <STDIN>);
    exit 0 if ($id eq ""); # If empty string, exit.
}

But it doesn't seem to work if I pass, eg, the following:

perl "myperlroutine.pl" "" "Mickey Mouse" "Entry"

The command window (I'm running this on Windows) briefly appears and then immediately disappears.

Am I missing something obvious?

You are using the low precedence not where you should be using the high precedence ! .

So you are saying:

if ( not( defined $id || $id eq "" ) )

which is like:

if ( ! defined $id && $id ne '' )

which is always false.

So do

if ( ! defined $id || $id eq '' )

instead.

With Perl 5.12 and later, length() no longer warns when passed undef, which is incredibly convenient. So you can do simply:

if ( ! length $id ) {

which is short code, but it could be inefficient if $id could be a long UTF-8 string, where determining the length is hard. There I would be more inclined to do:

if ( ( $id // '' ) eq '' ) {

But that's not super readable unless you are familiar with that idiom.

You have received good answers explaining exactly what is wrong with your code. But no one has commented on the bigger picture.

Using positional arguments like this is (as you can see) problematic when the arguments become optional. In this situation, it's a far better idea to use named arguments. The standard Perl library comes with two modules ( Getopt::Std and Getopt::Long ) which make it easy to create flexible sets of command-line options. I recommend that you look at using one of those.

This pretty much covers anything you're looking for:

 if ( not length( $id )) { 
     ...
 }

AKA:

 unless ( length $id ) { 
     ...
 }

If your window is instantly disappearing that usually indicates a compilation error. You should open the command window and run the script from the command line:

  • Click "start"
  • type "cmd" into the search bar and hit Enter .

Then run your script from the command line as follows:

perl full_path_to_script\script_name.pl

If you do this, the command window should not instantly close. Instead, it should give some feedback on why your script is failing to run. If you still can't figure out why it is failing after doing that, you should post your compilation errors as well and we can take a look at them.

Also, ysth is correct . You should be using "!" instead of "not".

Example:

if ((!defined $id) || ($id eq '')) {
    print "Enter ID number: ";
    chomp ($id = <STDIN>);
    exit 0 if ($id eq ""); # If empty string, exit.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM