http://www.perlmonks.org?node_id=935203


in reply to Command line options

rpelak:

For the specific case you cited, you don't really need to know where the value comes from--you just want the "right" one to "win". I tend to do it by calculating the least interesting value first, then overwriting with the "better" values. In that way, I don't really care which value wins. I just know that the last (most important) one does. For example:

use strict; use warnings; use Getopt::Long; # General default value my $foo = 'default'; # Let environment override the default if (defined $ENV{FUBAR}) { $foo = $ENV{FUBAR}; } # The command-line option overwrites if it exists GetOptions("foo=s"=>\$foo); print "The foo parameter is '$foo'\n";

A few different usages gives:

$ perl foo.pl The foo parameter is 'default' $ export FUBAR='Gragnar' $ perl foo.pl The foo parameter is 'Gragnar' $ perl foo.pl -foo=BARBAZ The foo parameter is 'BARBAZ' $

This technique has its shortcomings, obviously, such as when (a) the computation is expensive or (b) has undesirable side effects.

...roboticus

When your only tool is a hammer, all problems look like your thumb.

Replies are listed 'Best First'.
Re^2: Command line options
by rpelak (Sexton) on Nov 01, 2011 at 20:26 UTC
    Good points... I had to look back at some code to figure out why I had determined that wouldn't work...
    The derivations could also look at values of other options to do their deriving. And yeah, you can get in circles this way, but in many cases it is clean.
    And of course you could also want to only look at another options value as part of your derivation if the user actually gave that value, rather than if it was the default...
      Having "special interactions" among different options seems like a bad idea. If you actually have specific cases where the kinds of logic you describe seem necessary, there's probably a way to simplify the interface. If you're just imagining that such situations might arise, don't waste your time worrying about it, because if they do, there should be a way to simplify things.

      You write user manuals for these tools, right? If an accurate description of how the options work is too complicated, users are going to use it the wrong way and get results they don't want.

        I do have specific situations...
        They are hard to describe as they are, without a lot of background, so I will try to adjust the situation to something that is more commonly known...

        Think build scripts design to build multiple tools independently...
        you run a command to do a build. If you are in a directory for a specific tool, it assumes that it the tool you want to build, if not there is a commonly tool you likely want to build, or you can tell it which one. So if you tell it, that always wins. As for derived, think of the platform, different tools have different platforms they can be built for... so a good default is hard to come by, but there may be one that is good for 80% of the tools, but if you determine that the tool is not one of those 80% (by derivation or user input) you want to derive the most likely platform for that tool, and unless the user gives you one specifically, you want to use the derived over the default.

        Now the obvious answer that jumps out, is to set the default to "" and then you will "know" if the user passed in a value as it isn't "". But in the real case, "" is a possible value that the user might pass, and in theory there isn't anything you could set the default to that might not be something the user might pass in. And of course giving it some crazy string and having that show up in the auto generated help text would be rather ugly, and shouldn't be needed. If only you knew the value came from the user vs the default, all would be well.

        also in the real case, the tool is used without any args 85% of the time, and in the same env, so it does the same thing. And that env doesn't provide enough to derive "all" of the args, so some have to have defaults of real values. Yet those same args that have to have real defaults, would be easily derived in many of the other 15% of uses. So you can't use a bogus default value to tell you if the user passed something in, and you have to let the user pass something in if they want, yet if they don't in some 15% of the cases the derived value is better then the default...

        Does that make sense?