Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

Re^4: Benifits of using hash rather than number of variables?

by duelafn (Vicar)
on Jul 21, 2011 at 14:33 UTC ( #915883=note: print w/replies, xml ) Need Help??

in reply to Re^3: Benifits of using hash rather than number of variables?
in thread Benifits of using hash rather than number of variables?

It will work fine for sub parameters. You can provide a list of keys as a second parameter to lock_keys:

sub whatever { my %params = @_; lock_keys %params, qw/ key1 key2 key3 /; say "Got key1" if $params{key1}; # ok say "Got key2" if $params{key2}; # ok say "Got key3" if $params{keye}; # Oops - BOOM! } whatever key2 => $value2; whatever keyq => $value1; # Hash has key 'keyq' which is not in the ne +w key set

For example, I use the following for parsing command-line options in my scripts:

use Getopt::Long qw/:config bundling/; use Hash::Util qw/ lock_keys /; our %OPT; my @OPT_SPEC = qw/ help|h version noact|no-act|dry-run DEBUG output|o= +s /; GetOptions \%OPT, @OPT_SPEC or ($OPT{help} = 1); lock_keys(%OPT, map /^(\w+)/, @OPT_SPEC);

Update 2: A diligent Anonymous monk actually tested this code (actually executing proposed code - what a concept) and pointed out that the initial lock_keys suggestion is sufficient. Updated the comments in the code above to reflect this.

Update: Add example where lock_keys is not quite sufficient... One could solve this in a couple ways without changing how whatever is called: Anonymous monk make all this unnecessary

# Option 1: use Params::Validate # Option 2: sub whatever { my @param_keys = qw/ key1 key2 key3 /; my %params = @_; $params{$_} //= undef for @param_keys; die "Invalid usage" if @param_keys != (keys %params); lock_keys %params; # ... } # Option 3: sub whatever { my %expected_params = map +($_,1), qw/ key1 key2 key3 /; my %params = @_; for (keys %params) { die "whatever: Unexpected named parameter $_" unless exists $e +xpected_params{$_}; } lock_keys %params, keys %expected_params; # ... }

Good Day,

Replies are listed 'Best First'.
Re^5: Benifits of using hash rather than number of variables?
by JavaFan (Canon) on Jul 21, 2011 at 14:59 UTC
    As you pointed out, it won't catch typos when calling the subroutine. Which is the important case.

    Since there's no reason to use the hash key more than once inside the subroutine, the protecting inside the subroutine is just overhead, adding absolutely nothing at all of value:

    sub whatever { my %params = @_; my $key1 = $params{key1}; my $key2 = $params{key2}; my $key3 = $params{key3}; ... neither %params, nor the key names are needed anymore ... }
    Alternatively, you can stick the key names in variables.

      Note: Updated my previous reply with various proposed solutions.

      Indeed, the initial implementation (lock_keys %params, qw/ key1 key2 key3 /;) is equivalent to your solution there. Though, my reading of the OP was that they wanted to use hashes rather than set a bunch of variables like that and lock_keys offers no less protection than the originally proposed Tie::Hash::Vivify.

      My personal use of lock_keys is restricted to command line option parsing and some cases where it is "easy" to set up on hashes that may be passed around or used a lot (for example, log file parsing as described in The value of declarations). If I were looking for a complete solution for subroutine arguments I would most likely reach for Params::Validate or similar since once you move beyond lock_keys %params, qw/ key1 key2 key3 /;, the added coding effort for proper validation (vs just verifying key names) isn't much.

      Good Day,

Re^5: Benifits of using hash rather than number of variables?
by Anonymous Monk on Jul 21, 2011 at 16:51 UTC
    whatever keyq => $value1; gives: Hash has key 'keyq' which is not in the new key set at ...

    Seems useful enough.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://915883]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (10)
As of 2018-06-25 19:51 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (128 votes). Check out past polls.