newbie01.perl has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

Am passing some command line arguments when running the Perl script. At the moment I am not doing any checking on the values passed from the command line arguments, that is the assumption is they are correct as passed although we need in some cases, some smart dude would want to impress and "complain" that the script is weak and does not check for values of command line arguments. My point is, if it works, that's it, am not writing one with the intention of having someone to test how to make the script fail especially if it is a rush-up scripts that has to be created ASAP.

Anyway, at some stage, I will want to check for values of command line arguments. Below is an excerpt from my script, it is all very rudimentary as I said so, it is a rush-up scripts.

use strict; use POSIX; use File::Basename; use Time::Local; use Benchmark; use DBI; my $BASE_DIR = "E:\\Backup\\Scripts"; my $EXPORT_DIR = "E:\\Backup\\Export"; my $perl_program = $^X; my $perl_script = $0; my $basename = basename($perl_script,".pl"); $ENV{'ORACLEDB_HOME'}= $ARGV[0]; $ENV{'ORACLE_SID'}= $ARGV[1]; ... ... ... and so on for the scripts to do other stuff ... based on the supplied argument ... ... there is no sub-routines of any kind, this script ... just do what it's told to do in a sequence of commands ... :-) ... ...

Now, my question is can I check for the values of the command line arguments via a subroutine? by changing the Perl script as below, I think. Is there any other way?

use strict; use POSIX; use File::Basename; use Time::Local; use Benchmark; use DBI; my $BASE_DIR = "E:\\Backup\\Scripts"; my $EXPORT_DIR = "E:\\Backup\\Export"; my $perl_program = $^X; my $perl_script = $0; my $basename = basename($perl_script,".pl"); sub check_arguments{ ... ... check arguments whether they are valid or not ... } # MAIN sub check_arguments $ARGV[0] $ARGV[1];

One last questions, are all variables global unless defined with my in which case, it is local? Thanks in advance.

Replies are listed 'Best First'.
Re: Checking the command line arguments
by moritz (Cardinal) on Dec 03, 2009 at 13:02 UTC
    A subroutine works, but you should use it a bit differently:
    if (arguments_ok(@ARGV)) { # do something } else { # complain loudly }

    You might also be interested in the FindBin core module, which might be more reliable than $0 . ".pl"

    Also not that if you want to start another process via system, you should use the LIST form so that spaces in arguments don't confuse your program:

    system($^X, "some_script.pl", @ARGV);
Re: Checking the command line arguments
by BioLion (Curate) on Dec 03, 2009 at 13:27 UTC

    Getopt::Std::WithCheck is also a nice way of getting your args, checking they are what they should be, providing defaults, usage warnings etc... all in one go (once you have it set up as you want).

    For checking the validity of your args (not sure what they are), there are also a lot of modules for this too

  • Data::Validate is one i ues a lot
  • Test::File for checking filenames that are passed etc...

  • Have a hunt around on CPAN, as this sort of thing is a common problem when creating programs and a lot of solutions are available at little time cost to yourself!

    Just a something something...
Re: Checking the command line arguments
by cdarke (Prior) on Dec 03, 2009 at 13:23 UTC
    are all variables global unless defined with my

    Well, it depends what you mean by 'global'. If you declare a my variable outside a subroutine then it is 'global' in the sense that it is visible to a subroutine, as for example your $BASE_DIR variable. However it is not visible to another package. Declaring using our creates a package variable, which is visible outside. Since you are using strict (that's good) then you will have to declare variables using my or our (or the older use vars).

    in which case, it is local?
    Ah. Be careful of your terminology. A third way is to declare a variable as local, which probably does not do what you would think. It temporally overrides the value of a package variable, and is mostly used with system variables like $, $" $/ and so on.
      However it is not visible to another package.

      Be careful here. Lexical variables don't care about packages, lexicals and packages are completely orthogonal concepts.

      use strict; my $x = 42; { package OtherPackge; print $x, "\n"; }

      Lexical variables are visible within the current block, and each file is implicitly enclosed in a block.