Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Accept user options with defaults and report unknowns.

by BrowserUk (Patriarch)
on May 25, 2003 at 17:04 UTC ( [id://260707]=CUFP: print w/replies, xml ) Need Help??

Much of the code I looked for examples of accepting user options and suppplying defaults for those not specified seemed to go through extraordinary contortions, loops and stuff to do it. This is what I settled on.
sub myfunction { my %defs = ( optionA=>2e6, optionB=>'defA', optionC=>'defB' ); my %user = ( %defs, @_ ); my %opts; @opts{keys %defs} = delete @user{keys %defs}; carp "Unknown options: '@{[ %user ]}' ignored." if %user; # %opts user known user supplied options # defaults for unsupplied options # Warning issued about unknown options # do stuff. }

Replies are listed 'Best First'.
Re: Accept user options with defaults and report unknowns.
by DrHyde (Prior) on May 27, 2003 at 13:17 UTC
    Params::Validate would seem to do the job.

      At what cost? to replace 3 simple lines?

      Say hi to Mr. Jeckle:)


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
Re: Accept user options with defaults and report unknowns.
by Aristotle (Chancellor) on May 30, 2003 at 00:15 UTC
    I would generalize that a bit unless I only need it once.
    sub get_unknown_keys (\%;) { my $hash = shift; my %allow; @allow{keys %$hash} = (); delete @allow{@_}; return keys %allow; } sub func { my %arg = ( foo => 1, bar => 'baz', quux => 42 ); my @allow = keys %arg; %arg = (%arg, @_); if(my @unknown = get_unknown_keys %arg, @allow) { carp "Ignoring unkown parameters: @unknown"; delete @arg{@unknown}; } # do stuff. }
    I have to say I quite like the way delete @arg{@unknown} reads.

    Makeshifts last the longest.

      Part of me agree's, and enevitably, part doesn't.

      Three lines repeated twice becomes a sub? Use the sub in two modules, it becomes a module in its own right? Then it need pod, and a name and hell, I might as well throw in some validation of the values, so I need an api. Might as well make it OO. Oops! I re-invented Params::Validate.

      Now why did I reject Params::Validate above? Oh. because I couldn't see the point in replacing 3 lines with a module and 3 lines.

      use My::Params::Validate; my $validator = My::Params::Validate->new( Foo=>[ qw[foo|bar|qux] ], Bar=>[ 100 .. 1000 ], Qux=>[ 2e9, 3e8 ], ); sub myfunction{ my %opts = $validator %defs, @_; ... }

      Ah! But now I need some code to validate the arguements to My::Params::Validate.

      Should I subclass it? Use a virtual base class? What about exception handling?

      OMG - I just re-invented Java:)

      I do like delete @args{@unknown} (Note the S. I'll have to see if I can work that in somewhere:)


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (7)
As of 2024-03-28 11:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found