Testing a hash to see if it has values for all required keys. Extraneous keys are okay.

use strict; use warnings; use Test::More tests => 3; my (%required,%over,%under,%partial); $required{$_} = 1 for qw/header detail trailer/; $over{$_} = $_ for qw/title header subject detail trailer postscript/; $under{$_} = $_ for qw/header trailer/; $partial{$_} = $_ for qw/header trailer/; $partial{detail} = undef; ok(test_it(%over),'checking %over for required keys'); ok(test_it(%under),'checking %under for required keys'); ok(test_it(%partial),'checking %partial for required keys'); sub test_it { my %h = @_; # return (grep {$required{$_} && $h{$_}} keys %h) == (keys %required) +; return (grep {$required{$_} && defined $h{$_}} keys %h) == (keys %r +equired); }

Update: use of defined suggested by choroba. I would have run into this because 0 is a value I would encounter.

But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

Replies are listed 'Best First'.
Re: Does hash contain minimum keys?
by choroba (Bishop) on Nov 11, 2016 at 17:24 UTC
    Maybe add a defined after the && if zero is a valid value? See also HASH COMPARISONS in Test::Deep .

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Does hash contain minimum keys?
by emshach (Initiate) on Dec 13, 2016 at 21:46 UTC

    In this example %required doesn't need to be a hash, and since that's what you're checking against, that's what you should search. You could also use prototyping to avoid building a whole new hash each time, so we'd end up with something like:

    sub test_it (\%) { my ($h) = @_; return (keys (%$h) >= @required && !grep { !defined($h->{$_}) } @required); # return true if the list of missing required keys is empty }