deep27ak has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I have a main function which almost works but it it lacks at someplaces.

My script's requirement is that it should run by default without any arguments but if the user wants to run the script with a custom file then he/she should use -c "filename with path"

It would be good if the script could also validate the xml file which is being passed as an argument under elsif condition

Main Function
if (@ARGV > 0) { if ( $ARGV[0] eq "-c") { if ( ! -e "$ARGV[1]" ) { print "Provided xml file doesnot exists\n"; } elsif ( -f "$ARGV[1]") { $controlfile = $ARGV[1]; parse_xml(); update_exports(); } } else { usage (); } } elsif (@ARGV eq 0) { $controlfile = 'network.xml'; parse_xml(); update_exports(); exit 0; }
Here everything works untill I only run
# perl script.pl -c Use of uninitialized value $ARGV[1] in string at nfs_security.pl line +171. Provided xml file doesnot exists

Here how can I print a warning message along with usage so that when $ARGV1 is not provided throw a warning

Replies are listed 'Best First'.
Re: throw a warning if no argument were passed
by Corion (Patriarch) on Sep 21, 2015 at 11:24 UTC

    Maybe consider using Getopt::Long instead of hand-rolling the argument parsing.

    Also consider looking at line 171 in your real script, and looking at why that warning is thrown there. For example, if $ARGV[1] is not defined, then that warning will be thrown. Also see splain and warnings.

Re: throw a warning if no argument were passed
by karlgoethebier (Abbot) on Sep 21, 2015 at 11:49 UTC
Re: throw a warning if no argument were passed
by Laurent_R (Canon) on Sep 21, 2015 at 16:24 UTC
    Yes, you should probably consider using Getopt::Long.

    But, as for your script, it seems that the problem is the following:

    if (@ARGV > 0) { if ( $ARGV[0] eq "-c") { if ( ! -e "$ARGV[1]" ) { print "Provided xml file doesnot exists\n"; } elsif ( -f "$ARGV[1]") { $controlfile = $ARGV[1]; parse_xml(); update_exports(); } } else { #...
    If (@ARGV > 0), then the number or arguments should really be 2 (you need 0 or 2 arguments, the option and the file name), so that if (@ARGV == 1) (only one argument) it is also an error, but your code is not checking that, hence the problem when you pass the option flag but not the file name.

    In brief, if (@ARGV > 0), then you should check that you have (@ARGV == 2), or else call the usage() sub.

Re: throw a warning if no argument were passed
by afoken (Chancellor) on Sep 21, 2015 at 19:23 UTC

    A tiny hint:

     elsif (@ARGV eq 0) {

    may work "accidentally", but you want == to compare numbers. (How to remember that.)

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      Yeah, in addition to your correct comment about eq vs. ==, I also noticed yesterday, but did not mention then (because it appeared to be slightly off-topic), that this test is also actually useless, since it comes in the else branch of a condition testing if (@ARGV > 0). Since the number of elements of an array can only be zero or a positive integer, it can only be 0 when it is strictly smaller that 1.
Re: throw a warning if no argument were passed
by Anonymous Monk on Sep 21, 2015 at 11:24 UTC
    Data::Dump::dd(\@ARGV)