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

Howdy,

Here is my scenario:

So far, so good (I think)... So I started playing around with Getopts:Std. I added code to my library like so:

use Getopt::Std; getopts('fs', \%opts);

I found that if I then referred to %opts from within the library, like so:

if ($opts{s}) { #do stuff }
...it all works as expected. But if I try to refer to %opts from outside the library, I get:
Global symbol "%opts" requires explicit package name.....

The reason for the error is pretty obvious - the script doesn't know about %opts, and as I'm using strict, it barfs. But I'm not sure where to go from here. I'm guessing that I need to create a package, and refer to that - but I'm afraid that this is uncharted territory for me. I've tried putting this:

{ package FOO; use Getopt::Std; getopts('fs', \%opts); }
in the library, but that doesn't work.

Can somebody point me in the right direction please?

Thanks,
Darren :)

Replies are listed 'Best First'.
Re: Sharing Getopts::Std amongst several related scripts
by ikegami (Patriarch) on Dec 13, 2005 at 15:35 UTC
    Use a package (our) variable instead of a lexical (my) variable:
    package main; use Getopt::Std; our %opts; getopts('fs', \%opts); package Foo; if ($main::opts{s}) { #do stuff } package Bar; if ($main::opts{s}) { #do stuff }

    You can even create an alias:

    package main; use Getopt::Std; our %opts; getopts('fs', \%opts); package Foo; our %opts; *opts = \%main::opts; if ($opts{s}) { #do stuff } package Bar; our %opts; *opts = \%main::opts; if ($opts{s}) { #do stuff }

    I hate referencing main explicitely, so I prefer importing the symbol from a module that will handle the options:

    # Optionally in seperate file Opts.pm package Opts; use Getopt::Std; our %opts; our @EXPORT = qw( %opts ); our @ISA = 'Exporter'; require Exporter; getopts('fs', \%opts); 1; package Foo; use Opts qw( %opts ); if ($opts{s}) { #do stuff } package Bar; use Opts qw( %opts ); # Safe to do multiple times. if ($opts{s}) { #do stuff }
      Thank you very much for such a comprehensive answer :)

      I've changed the code in my library to look like so:

      { package OPTS; use Getopt::Std; our %opts; getopts('fs', \%opts); }
      and in the script that requires the library, I have:
      our %opts; *opts = \%OPTS::opts; if ($OPTS::opts{f}) { #do stuff }
      and it all seems to work now the way I want it to. Although I'm still not really sure I fully understand what's going on here. I've just been flicking through Chapter 10 (Packages) in my trusty Camel Book. I think I need to study it some more before I get the hang of this.

      But thanks again :)

        our %opts; *opts = \%OPTS::opts; if ($OPTS::opts{f}) { #do stuff }
        can be simplified to
        if ($OPTS::opts{f}) { #do stuff }
        or
        our %opts; *opts = \%OPTS::opts; if ($opts{f}) { #do stuff }