<?xml version="1.0" encoding="windows-1252"?>
<node id="915883" title="Re^4: Benifits of using hash rather than number of variables?" created="2011-07-21 10:33:54" updated="2011-07-21 10:33:54">
<type id="11">
note</type>
<author id="53268">
duelafn</author>
<data>
<field name="doctext">
&lt;p&gt;It will work fine for sub parameters. You can provide a list of keys as a second parameter to lock_keys:&lt;/p&gt;
&lt;code&gt;
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 =&gt; $value2;
whatever keyq =&gt; $value1; # Hash has key 'keyq' which is not in the new key set
&lt;/code&gt;

&lt;p&gt;For example, I use the following for parsing command-line options in my scripts:&lt;/p&gt;
&lt;code&gt;
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);
&lt;/code&gt;
&lt;p&gt;&lt;b&gt;Update 2:&lt;/b&gt; 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.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; &lt;strike&gt;Add example where lock_keys is not quite sufficient... One could solve this in a couple ways without changing how &lt;code&gt;whatever&lt;/code&gt; is called:&lt;/strike&gt; Anonymous monk make all this unnecessary&lt;/p&gt;
&lt;code&gt;
# 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 $expected_params{$_};
    }

    lock_keys %params, keys %expected_params;
    # ...
}
&lt;/code&gt;
&lt;div class="pmsig"&gt;&lt;div class="pmsig-53268"&gt;
&lt;p&gt;Good Day,&lt;br&gt;&amp;nbsp; &amp;nbsp; Dean&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;</field>
<field name="root_node">
915563</field>
<field name="parent_node">
915867</field>
</data>
</node>
