perltcsh

How can I pass arguments for a subroutine from the command line


First off, my background is primarily in Python and I am relatively new at using Perl.

I am using tcsh for passing options into my .pl file.

In my code I have:

if( scalar @ARGV != 1)
{
    help();
    exit;
}

# Loading configuration file and parameters
our %configuration = load_configuration($ARGV[0]);

# all the scripts must be run for every configuration
my @allConfs = ("original");

sub Collimator 
{ 
     my $z = -25.0; 
     my %detector = init_det();
     
     $detector{"pos"}         = "0*cm 0.0*cm $z*cm"
}


foreach my $conf ( @allConfs )
{ 
    $configuration{"variation"} = $conf ;
    
     #other geometries ....
    
    Collimator();
}

I want to add something that allows me to change the parameters of the subroutine in the .pl file from the command line. Currently, to generate the geometry I pass the following command into the tcsh CLI: perl file.pl config.dat. What I want is to be able to pass in something like this: perl file.pl config.dat -20.0.

I'm thinking that I need to add something to the effect of:

if($ARGV[1]){
    $z = ARGV[1]}

However, I am not sure how to properly implement this. Is this something that I would specify within the subroutine itself or outside of it with the loading of the configuration file?


Solution

  • Use a library to handle command-line arguments, and Getopt::Long is excellent

    use warnings;
    use strict;
    
    use Getopt::Long;
    
    my ($config_file, @AllConfs); 
    my ($live, $dry_run) = (1, 0);
    my $z;
    
    GetOptions( 
        'config-file=s'  => \$config_file, 
        'options-conf=s' => \@AllConfs, 
        'geom|g=f'       => \$z,
        'live!'          => \$live,
        'dry-run'        => sub { $dry_run = 1; $live = 0 },
        # etc
    );
    
    # Loading configuration file and parameters
    # (Does it ===really=== need to be "our" variable?)
    our %configuration = load_configuration($config_file);
    
    my @data_files = @ARGV;  # unnamed arguments, perhaps submitted as well
    

    Options may be abbreviated as long as they are unambiguous so with my somewhat random sample above the program can be invoked for example as

    prog.pl --conf filename -o original -o bare  -g -25.0  data-file(s)
    

    (Or whatever options for @AllConf are.) Providing explicitly g as another name for geom makes it a proper name, not an abbreviation (it doesn't "compete" with others).

    Note that one can use -- or just -, and choose shorter or long(er) names for convenience or clarity etc. We get options, and there is a lot more than this little scoop, see docs.

    Once the (named) options have been processed the rest on the command line is available in @ARGV, so one can mix and match arguments that way. Unnamed arguments are often used for file names. (The module offers a way to deal with those in some capacity as well.)