Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

dispatch table of functions and arguments

by Sihal (Pilgrim)
on Sep 03, 2002 at 13:09 UTC ( #194753=perlquestion: print w/ replies, xml ) Need Help??
Sihal has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, I'm trying to build a dispatch table wich looks like this:
my %function_to_compute_taste_value = { ClickInterval => \&compute_interval , ClickInterstice => \&compute_interstice , EffInactivity => \&compute_inact_and_expo_effective , Exposure => \&get_exposure_service } ;
My question being: I want to pass very different args to each of these subs. I wonder If there is a really clean way to do it. Thanx a lot!

edited: Tue Sep 3 13:09:41 2002 by jeffa - code tags and spacing

Comment on dispatch table of functions and arguments
Download Code
Re: dispatch table of functions and arguments
by fglock (Vicar) on Sep 03, 2002 at 13:16 UTC
    %func = { Click => { func => \&compute, param => [ @param ] }, Click2 => { func => \&compute2, param => [ @param2 ] }, };
    ----------

    update: How to set a parameter:

    $func{Click2}{param} = [ 1, 2, "hello" ];

    How to call a function:

    &{ $func{Click2}{func} } ( @{$func{Click2}{param}} );

    update: corrected @{} in func call

    ----------

    There are many more ways to do it.

    Also:

    ... Click => { func => \&compute, param => \@param }, ...

    Or:

    ... Click => [ \&compute, \@param ], ...
(jeffa) Re: dispatch table of functions and arguments
by jeffa (Chancellor) on Sep 03, 2002 at 13:31 UTC
    fglock has you covered ... here is some more code that illustrates how to pull the pieces out and use them:
    use strict; my %dispatch = ( foo => [\&foo,qw(5 * 4)], bar => [\&bar,'HELLO'], ); for (keys %dispatch) { my ($sub,@args) = @{$dispatch{$_}}; print $sub->(@args),"\n"; } sub foo { my ($n1,$op,$n2) = @_; return eval "$n1 $op $n2"; } sub bar { return ucfirst lc shift; }

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: dispatch table of functions and arguments
by bronto (Priest) on Sep 03, 2002 at 13:43 UTC

    Surely using positional parameters causes serious braindamage :-)

    A solution could be using named parameters (a hash, I mean). For example, parameters for ClickInterval and Exposure could be respectively:

    %param = ( firstClick => 12345, secondClick => 21345) ;

    and

    %param = ( 'value' => 911 ) ; # call for help on "Exposure"

    Once you compose the %param hash someway, you could end up your code with a simple call:

    my @res = $function_etc_etc{$a_function}->(%params) ;

    and each sub will get only the parameters it deserves :-)

    Ciao!
    --bronto

    # Another Perl edition of a song:
    # The End, by The Beatles
    END {
      $you->take($love) eq $you->made($love) ;
    }

      thanx a lot for your replies but I still fail to understand how to pass the args.... oki I'll re read the node
      YES i understand that. however, what would be really nice, is if I could build a dispatch table for the parameters as well, and then give a value to the params somewhere in my code and then use it whenever I please. don't know if I clear
        fglock your solution still isn't quite like what I imagined : imaghine I have 3 parameters $toto, $titi, $tata.
        I'm inside a while(){} and I want to call some funcs of my dispatch table with either $toto, $titi, or $tata ( depending of the type of data i'm fed) but keeping in mind that the values of $titi, $toto, $tata change at every iteration (because of the data i'm fed) ..... is it possible?
      In fact what I currently do is kinda the same as you suiggest, but i have to pass around in a hash of 15 arguments ( and then the subs figure out wich ones they need ) so it's kinda a waste, which is why I want to refine this mechanism
Re: dispatch table of functions and arguments
by oylee (Pilgrim) on Sep 03, 2002 at 16:44 UTC
    Currying closures might be useful here, but that depends on when you are building the dispatch table if I understand your problem correctly. If you don't mind wasting efficiency, you might want to lift out common arguments to the subs (if any exist) to the dispatch call site and build the dispatch table like this during each iteration of the while loop:

    my %dispatcher = ( foo => compute_interval($titi), bar => compute_interstice($tata), baz => compute_inact_and_expo_effective($toto), qux => get_exposure_service($bling) ); $dispatcher{$action}->(<insert_common_args_here>) if exists($dispatche +r{$action}); sub compute_interval { my $args = shift; return sub { # do something useful with args here.. } } sub compute_interstice { my $args = shift; return sub { # and so on } }

    I'm sure there's a better way to do this that my idiocy is incapable of figuring out right now too.
    There are lots of better resources regarding how to use closures available -- try searching for the word 'closures' on this site for more info.

    Anonymous Lee

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://194753]
Approved by ybiC
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (7)
As of 2014-07-12 18:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (240 votes), past polls