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

After having received a lot of helpful advice in the thread staring with Avoiding if/else knots, I have decided to go for the dispatch table approach. However, even though I don't really have the problem of non-integer ranges, I still don't want to have to construct a table with around, say, 60 combinations of which only around, say, 20 are distinct. So maybe "A|*|*|*" maps to Case 1, "B|A|*|*" maps to Case 2, "B|B|*|*" maps to Case 3, etc.

To get around this I thought I would just use regexps to match groups of conditions and map them onto a set of generic keys which represent the unique cases. Thus for a given case, I would dynamically create a string of delimited fields from the current conditions and then try to match certain parts of the string. In the matching case I would then set the generic key, otherwise I would try the next match. As the cases are all disjoint from the point of view of pattern matching, the order in which I do the matching is not important. Can anyone see any possible drawbacks to this approach?

Thanks,

loris


"It took Loris ten minutes to eat a satsuma . . . twenty minutes to get from one end of his branch to the other . . . and an hour to scratch his bottom. But Slow Loris didn't care. He had a secret . . ."

Replies are listed 'Best First'.
Re: Avoiding if/else knots II
by shmem (Chancellor) on Aug 30, 2006 at 08:04 UTC
    I still don't want to have to construct a table with around, say, 60 combinations of which only around, say, 20 are distinct.
    I'd also take the approach to normalize the 60 posibilities, i.e. coerce them into unique keys in the dispatchtable, with e.g.
    $key = 'default'; $case =~ s/$reg2// && ($key = 'a'); $case =~ s/$reg1// and do { whatever(); $key = 'b' }; ...
    and finally dispatch via a table
    $dispatch{$key}->(@args);
    Can anyone see any possible drawbacks to this approach?

    Not yet, since neither context nor implementation are visible...

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

      I'm asking myself what's the advantage of first mapping values to keys and then dispatching the keys via a hash table instead of skipping the key and dispatching directly.

      So in all the cases where you have a $key= somethin you could also write down a call of a subroutine handling this key. Except for the default case of course.

      I'd write your example like this:

      SWITCH: for ( $myValue ) { /$reg2/ && do { sub_for_key_a(); last SWITCH; }; /$reg1/ && do { whatever(); sub_for_key_b(); last SWITCH; }; #default sub_for_default(); } # END SWITCH

      s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
      +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
        TIMTOWTDI - I wanted to give an example of the m// && do {} idiom which was missing from the OP's previous thread. Since I don't know about the specifics, I wrote it somewhat generic. Depending on cases the $key or $case could be modified etc.

        As for your example, what good is it to use a labelled loop for a list containing one variable? ;-)

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Avoiding if/else knots II
by polettix (Vicar) on Aug 30, 2006 at 09:57 UTC
Re: Avoiding if/else knots II
by Anonymous Monk on Aug 30, 2006 at 16:50 UTC
    When the order is not important you can insert "()" around the constant parts of the keys and match $m=join"|",keys%table;$code=~/$m/ then you can dispatch on ($m=~/|([^|]*$1[^|]*)|/)[1].