Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re^2: GetOpt Organization (!hash)

by tye (Sage)
on Mar 09, 2015 at 14:50 UTC ( [id://1119333]=note: print w/replies, xml ) Need Help??


in reply to Re: GetOpt Organization
in thread GetOpt Organization

Whenever I touch Getopt::Long-using code that uses a hash, I usually change it to something that uses variables. In many of those cases, there are actually places in the code using an option name that isn't one of the ones populated by the call. "use strict" prevents such mistakes when variables are used.

I also prefer to reduce the scope of many of the options. Instead of making the hash available "everywhere", I can often make it clearer which options impact the behavior of a particular sub. Or that some option(s) impact nothing other than some small scope.

- tye        

Replies are listed 'Best First'.
Re^3: GetOpt Organization (!hash)
by karlgoethebier (Abbot) on Mar 09, 2015 at 17:55 UTC
    "I also prefer to reduce the scope of many of the options. Instead of making the hash available "everywhere", I can often make it clearer which options impact the behavior of a particular sub. Or that some option(s) impact nothing other than some small scope."

    Fascinating.

    But to be honest, i'm a bit unsure if i guessed right what you mean.

    Or in other words: IMHO there is nothing wrong with this idiom:

    MAIN: { my %options; GetOptions(\%options, "foo", "bar"); nose ($options{foo}, $options{bar}); } sub nose { my ($foo, $bar) = @_; # stuff my $cuke; }

    N.B.: First time post of untested code.

    Thank you very much for advice and best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

      i'm a bit unsure if i guessed right what you mean

      nose ($options{foo}, $options{bar});

      That covers "I can often make it clearer which options impact the behavior of a particular sub". But it doesn't cover any of the other cases.

      If there are any places that have access to the hash, then I have to go search in those places to see if 'foo' or 'bar' is used in those places. Of course, perhaps you never give access to the hash to any place, in which case what is the point of having a hash?

      But it is fairly common for some command-line options to impact many different places such that it is a pain to pass those options through every layer to every place that might care. And one of the benefits of variables is that you can distinguish the scope of each option.

      our $Verbose = 0; # Used tons of different places so is global my @files = cmd_opts( @ARGV ); ... sub cmd_opts { my @args = @_; my $mod = 0; GetOptionsFromArray( \@args, 'verbose|v' => \$Verbose, 'modified|m' => \$mod, ... return find_files( $mod, @args ); }

      Without looking any further, I can tell that --modified only impacts find_files().

      Another advantage is that you don't have to match the name you use in your code with the name you use on the command line. It might make perfect sense for --line-number to mean that you want each output line to be labeled with a number (like 'grep') while, in the code, line_number means the number that will be prepended so --line-number actually sets $label_output.

      It is nice to improve the command-line interface with better option names without having to do a global search/replace in the code or to refactor code to use better names without having to break backward compatibility of the command-line interface.

      But I still think the biggest advantage is that "use strict" tells me if I spell the option name differently in different places, catching a bug for me.

      - tye        

        Thank you very much tye for your explanation.

        I try to think this one step ahead.

        Consider this simple example:

        my %hash; foo(\%hash); bar(\%hash); sub foo{ my $ref = shift; } sub bar { my $ref = shift; } # perhaps many more

        So a cleverle might come and say: "Passing around these refs and dereferencing them all the time is a pain" - i make it so instead:

        our %hash; foo(); bar(); sub foo{ our %hash; } sub bar { our %hash; }

        IMHO this idea is, with all due respect, debatable. Or it is against the pure doctrine, as you like.

        My best regards, Karl

        P.S.: Daddy says globals are the root of all evil ;-)

        «The Crux of the Biscuit is the Apostrophe»

Re^3: GetOpt Organization (!hash)
by choroba (Cardinal) on Mar 09, 2015 at 22:31 UTC
    Excuse my slow wit, but I can't see how a lexical scalar is less "everywhere" than a lexical hash? How do you reduce the scope of options?
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1119333]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (2)
As of 2024-04-26 02:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found