Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

multiple keys - one value

by japhy (Canon)
on Sep 27, 2000 at 21:44 UTC ( #34248=note: print w/replies, xml ) Need Help??

in reply to using a hash of functions

Wouldn't it be nice if there was some idiom (say, a magical hash...) that would allow me to say:
%hash = ( HELP => sub { ... }, '?' => $_{HELP}, QUIT => sub { ... }, EXIT => $_{QUIT}, LEAVE => $_{QUIT}, );
Instead of
%hash = ( HELP => sub { ... }, QUIT => sub { ... }, ); $hash{'?'} = $hash{HELP}; $hash{EXIT} = $hash{LEAVE} = $hash{QUIT};


Replies are listed 'Best First'.
RE: multiple keys - one value
by merlyn (Sage) on Sep 27, 2000 at 23:34 UTC
      Thank you, Randal. That looks about right, and perfectly Perlish.

      I know I'm only 3 years late, but could someone explain/dissect in teaching terms, just what merlyn did. /msg me if you wouldn't mind so I know it's up. Thanks.

      "A little yeast leavens the whole dough."
(jcwren) RE: multiple keys - one value
by jcwren (Prior) on Sep 27, 2000 at 21:56 UTC
    This is a little clumsy, but you could have  '?' => 'HELP', etc, then use a loop at startup that replaced non-code refs with the code ref of the hash indice the value side points to.

    It doesn't completely solve the semantic problem, but if you rename a routine, you only have to touch it one place, and adding synonyms becomes trivial.
    #!/usr/local/bin/perl -w use strict; my %hash = ('HELP' => \&do_help, '?' => 'HELP', 'LIST' => \&do_list, 'SHOW' => 'LIST', 'TEST' => \&do_test, ); { while (my ($k, $v) = each (%hash)) { $hash {$k} = $hash {$v} if (ref $hash {$k} ne 'CODE'); } &{$hash {'HELP'}}; &{$hash {'?'}}; &{$hash {'LIST'}}; &{$hash {'SHOW'}}; &{$hash {'TEST'}}; } sub do_help {print "help\n"} sub do_list {print "list\n"} sub do_test {print "test\n"}

    e-mail jcwren
Re: multiple keys - one value
by sandfly (Beadle) on Sep 11, 2003 at 22:14 UTC
    If you're only duplicating one value, you can use
    my %h = ( HELP => $_ = sub {print "help\n"}, "?" => $_, SAVE => sub {print "save\n"}, );
    You have to use one variable per value though:
    my ($help, $save); my %h = ( HELP => $help = sub {print "help\n"}, "?" => $help, SAVE => $save = sub {print "save\n"}, EXIT => $save, );
      I'm trying to improve on sandfly's code by eliminating the need for temp variables, but getting into trouble. Why does the following code produce
      "Use of uninitialized value in subroutine entry at -e line 1.
      Undefined subroutine &main:: called at -e line 1."
      my %h=( HELP => sub {print qq(help\n)}, Q=>$h{HELP}, SAVE=>sub{print qq(save\n)} ); print $h{Q}();
      I have also tried it by separating the declaration and population of %h, to no avail.
        I suspect it's because $h{HELP} doesn't exist when you create the tuple Q=>$h{HELP}, as %h hasn't been assigned to at that time.

        Perhaps this will work for you:

        use Data::Dumper; my %h=( HELP => sub {print qq(help\n)}, SAVE=>sub{print qq(save\n)} ); $h{Q} = $h{HELP}; print Dumper(%h); print $h{Q}();
        $VAR1 = 'Q'; $VAR2 = sub { "DUMMY" }; $VAR3 = 'HELP'; $VAR4 = $VAR2; $VAR5 = 'SAVE'; $VAR6 = sub { "DUMMY" }; help 1
        Note that HELP and Q both use the same sub.

        Quantum Mechanics: The dreams stuff is made of

      OK I answered my own question based on one of my old writeups. It IS possible to eliminate the temporary variable by coding as follows:
      use strict; my %h; #Pre-declare so it can be referenced inside populating code %h=( HELP => sub {print qq(help\n)}, '?'=>sub{$h{HELP}()}, SAVE=>sub{print qq(save\n)}, EXIT=>sub{$h{SAVE}()} ); $h{'?'}(); $h{EXIT}();
      This prints the lines:

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (9)
As of 2018-11-14 13:00 GMT
Find Nodes?
    Voting Booth?
    My code is most likely broken because:

    Results (171 votes). Check out past polls.