Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

Re^3: How best to validate the keys of hashref arguments?

by cbeckley (Curate)
on Mar 16, 2017 at 17:48 UTC ( #1184910=note: print w/replies, xml ) Need Help??

in reply to Re^2: How best to validate the keys of hashref arguments?
in thread How best to validate the keys of hashref arguments?

Ah, forgot to ask, in the previous node, the line of code:

for my $k (keys %$init_hash) { $new_cmd->{$k} = $init_hash->{$k}; }

Is there a more idiomatic way to say that?


Replies are listed 'Best First'.
Re^4: How best to validate the keys of hashref arguments? (updated)
by haukex (Chancellor) on Mar 16, 2017 at 19:15 UTC
    for my $k (keys %$init_hash) { $new_cmd->{$k} = $init_hash->{$k}; }
    Is there a more idiomatic way to say that?

    Several, but it seems to me you're just copying over every value from %$init_hash into %$new_cmd, so it seems easiest to write:

    my %new_cmd = %$init_hash;

    This creates the same shallow copy of the hash that your current code is creating. You can lock_keys afterwards and incorrect keys will still cause corresponding errors. In the interest of TIMTOWTDI, here's a couple other solutions, most of which would be better applicable if you only wanted to copy over a subset of the keys. Note that the latter three clobber the entire contents of the hash, which should be fine in your case:

    sub ops_new_cmd { my ($init_hash) = @_; my %new_cmd; # -OR- #my %new_cmd = %$init_hash; lock_keys(%new_cmd, qw/name user host command/); my @keyset = keys %$init_hash; #for my $k (@keyset) { $new_cmd{$k} = $init_hash->{$k}; } # -OR- #$new_cmd{$_} = $init_hash->{$_} for @keyset; # -OR- %new_cmd = map { $_=>$init_hash->{$_} } @keyset; # -OR- #use 5.020; # For Key/Value Slices #%new_cmd = %$init_hash{ @keyset }; # -OR- #use experimental 'postderef'; # For Postfix Deref + Key/Value Sli +ces #%new_cmd = $init_hash->%{ @keyset }; return \%new_cmd }

    As for locked hashes, there was some discussion on P5P recently about them, but even if something were to happen to this feature, tied hashes would be an easy replacement. For example, a quick search on CPAN shows Tie::Hash::FixedKeys. On the other hand, if you start taking locked hashes that seriously, it's probably better to start moving to OO.

    Update in response to your reply, since I should have included it here in the first place: Personally what I currently use locked hashes for is mostly typo prevention, which is helpful during development, but could also be removed later without really affecting the code.

      Ah, well that last bit certainly nudges me a little harder towards OO, which is where I was leaning anyway, eventually ...

      In the short term Hash::Util::lock_ref_keys keeps me from looking for typos at run time, which was what I wanted ... initially ...

      Thanks again for all your input. Incredibly helpful, and enlightening, and oh-my-god-do-I-have-a-lot-to-learn!

Re^4: How best to validate the keys of hashref arguments?
by poj (Abbot) on Mar 16, 2017 at 19:03 UTC

    Like this perhaps ?

    #!perl use strict; use Hash::Util 'lock_keys'; use Data::Dumper ; # valid my $cmd = ops_new_cmd({ name=>1, user=>2, host=>3}); print Dumper $cmd; # not valid $cmd = ops_new_cmd({ name=>1, user=>2, hostt=>3}); sub ops_new_cmd { my ($init_hash) = @_; my @valid = qw( name user host key command status ssh_retcode ssh_retmsg output std_err cmd_ret_code cmd_ret_msg); + lock_keys(my %new_cmd,@valid); %new_cmd = %$init_hash; return \%new_cmd; }

      Yes it does, so does this:

      %$new_cmd = %$init_hash;

      Of course both assume I'm never gonna want to nest other hashrefs in my commands and initializers. I'm not, right? No. Never. Of course not ....

      Right. Ok, I'm going to use Clone.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1184910]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (4)
As of 2020-06-02 17:41 GMT
Find Nodes?
    Voting Booth?
    Do you really want to know if there is extraterrestrial life?

    Results (19 votes). Check out past polls.