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. |