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

Hello, I have a top level script called foo.pl I am passing a variable ($version) from the command line to it as one of the arguments to the script foo.pl foo.pl uses a couple of perl modules. I want to use this $version variable in a sub-routine of one of the perl modules Arithmetic.pm which is declared in foo.pl as  use Arithmetic; However I don't want to pass this variable from foo.pl as an argument to the sub-routine in Arithmetic.pm Is it possible to use variables in the top level script in the perl modules without passing it as an argument? (In my case use $variable declared in foo.pl in the sub-routine present in Arithmetic.pm) Thanks

Replies are listed 'Best First'.
Re: Using variables in top level script inside the perl modules
by GrandFather (Saint) on Nov 06, 2008 at 06:41 UTC
    I don't want to pass this variable from foo.pl

    Why not? By accessing or manipulating the variable as a global variable it can be very difficult to determine where the value comes from and when or why it changes. By explicitly passing the value in as an argument to a sub or constructor it is much easier to manage and debug the code relating to it.


    Perl reduces RSI - it saves typing
      I don't want to pass the variable as an argument because this foo.pl is an existing object oriented perl script and uses a lot of modules. The "$variable" will be used in a sub-routine in one of the module which is called from few other modules. If I have to pass the variable as an argument I would need to make changes in a lot of perl modules and the top level script which I would like to avoid as far as possible. I tried $::variable in a small dummy perl program but it does not seem to be working for me. Regards.

        Just a wild guess, but one conceivable reason that $::version would not work is that it's being used before it has been assigned its value. After all - as you have use Arithmetic; - the code is in an implicit BEGIN {...} block. In other words, in case there's any initialisation in the module, that code might be executed before $::version is ready.  For example, this would not work as one might expect at first:

        #!/usr/bin/perl use strict; use warnings; $::version = shift @ARGV; BEGIN { # emulate "use Arithmetic;" package Arithmetic; sub load_config { my $config = "/usr/local/myapp/$::version/properties"; print "config: $config\n"; # ... } load_config(); }

        In case you recognise any similarities to your scenario, you could try wrapping the assignment $::version = shift @ARGV; in a BEGIN block, which would make sure that things are being executed in the proper sequence.

        Pass the variable into the constructor for the object that needs it then. Besides, a little refactoring up front to add such a facility rather than hacking it in is almost always worth while.


        Perl reduces RSI - it saves typing
Re: Using variables in top level script inside the perl modules
by ikegami (Patriarch) on Nov 06, 2008 at 06:30 UTC
    Use $::version to get and set the variable. I'd personally move it into a small module.