ed_r has asked for the wisdom of the Perl Monks concerning the following question:

Good Day, This is the first time posting here so not sure if I have all the tags correct, if not sorry in advance, what I am trying to figure out is the correct syntax for a foreach statement with hash var, if it is possible that is. Very shorted code here:
%dat_mapping = (); %eng_mapping = ();
# in two different config files, a hash of arrays are created then slurped into the dat/eng mapping.
#then I start to pull things apart with.
foreach my $file_name (key (%dat_mapping)) { print "blah\n"; }

#okay here is the problem when working each hash by itself things work, but I was trying to build an anonymous sub where the hash goes such as:
#There is a lot of code with in this foreach statment, so trying not to have to duplicate that code, if the if statment can be reworked that would be great.
foreach my $file_name (key (sub { if ($hash_name eq 'dat') { return \%dat_mapping; } else { return \%eng_mapping: } } ) { print "blah\n"; }

Replies are listed 'Best First'.
Re: Hash with sub
by ikegami (Patriarch) on Mar 02, 2010 at 21:29 UTC
    • key should be keys
    • You never call the anon sub. ->() can be used to call it.
    • I don't see why you're using a sub at all.
    • Your anon sub returns a reference to a hash, not a hash, so you need to dereference it.
    for my $file_name ( keys %{ $hash_name eq 'dat' ? \%dat_mapping : \%eng_mapping } ) { ... }
    It would be more readable to break it up:
    my $hash = $hash_name eq 'dat' ? \%dat_mapping : \%eng_mapping; for my $file_name (keys %$hash) { ... }
      Thanks so much for the help on the if/then/else statement, I was over thinking how to approach the problem.
      my $hash = $hash_name eq 'dat' ? \%dat_mapping : \%eng_mapping; for my $file_name (keys %$hash) {
      Works great, I did not realize you could put a hash ref in a scaler, so this was something new to me also. Tks again.
Re: Hash with sub
by almut (Canon) on Mar 02, 2010 at 21:24 UTC

    Not really sure what you're trying to do... but if the idea is to loop over the keys of either the %dat_mapping or the %eng_mapping hash, depending on whether $hash_name is 'dat', then you could do

    #!/usr/bin/perl use strict; use warnings; my %dat_mapping = (foo => 1, bar => 2); my %eng_mapping = (FOO => 3, BAR => 4); my $hash_name = "dat"; for my $file_name (keys %{ $hash_name eq 'dat' ? \%dat_mapping : \%eng_mapping } ) { print "$file_name\n"; }

    See Conditional Operator