Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

Did you get much variation in the working results? It seems kind of straightforward to me, but maybe it's because I'm too used to that idiom.

Is a hash the recommended way to implement a dispatch table in Perl?
There are at least two ways to do this with an array (either the key is an enum, or you iterate over the array for each call), but I wanted to try with closures (with an OO interface, to hide the complexity of creating the closure chain when adding the callbacks):
use strict; use warnings; # Callback functions --------------------------------------- sub first_callback { my $z = shift; print "in first_callback, z=$z\n"; return 1; } sub last_callback { my $z = shift; print "in last_callback, z=$z\n"; return 2; } # Implementation of dispatch table ------------------------- # (You need to write this code) package Invoker { sub new { my ($class, $default) = @_; bless \(sub { shift; $default->(@_) }), $class; } sub add { my ($self, $key, $callback) = @_; my $alt = $$self; $$self = sub { my $name = shift; $name eq $key ? $callback->(@_) : + $alt->($name => @_) }; $self; } sub dispatch { my $self = shift; &{ $$self }(@_); } } sub default_callback { return -1; } my $invoker = Invoker->new(\&default_callback) ->add(first => \&first_callback) ->add(last => \&last_callback); sub invoker {$invoker->dispatch(@_)}; # Main program for testing --------------------------------- for my $name ( "first", "last", "fred" ) { my $rc = invoker( $name, $name . '-arg' ); print "$name: rc=$rc\n"; }
This creates a chain of closures that each contain a key, the corresponding callback and a ref to the next closure in the chain. If the name matches the key, the callback is called, otherwise the parameters are passed to the next closure in the chain.

At first this was just supposed to be a silly implementation, though it did make me think about your first question: a hash is the best solution when using an exact match to a key as the dispatch condition, but the (iterative) array-based or closure-based implementations can accept any condition (though the only advantage of the closure-based solution over array-based is that it's more fun).

Edit: the init method has been renamed new, because I don't know why I didn't just do that in the first place. And made the explanation more complete


In reply to Re: Rosetta Dispatch Table by Eily
in thread Rosetta Dispatch Table (Interview Question) by eyepopslikeamosquito

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2024-04-20 00:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found