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