Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Re: Switch/case as a jump table with C-style fall-through

by dragonchild (Archbishop)
on May 12, 2005 at 13:18 UTC ( #456376=note: print w/replies, xml ) Need Help??

in reply to Switch/case as a dispatch table with C-style fall-through

Basically, you're trying to come up with an API for a generalized switch statement without using source filters in Perl5. The actual mechanics, frankly, are irrelevant.

While I don't have much in the way of implementation suggestions, I do have a few requirements that I'd like to see from a switch statement. You may already implement some of these - I haven't checked.

  • Ordering of cases. This is very important with fall-through, because I may only want fall-through to a specific location. So, something like:
    switch (i) { 0,1: foo(); 2: bar(); break; 3: baz(); break; };
    0 and 1 must fall through to 2, but not 3. It also matters with the case of regex matches (q.v. below).
  • Smart matching. If I give you '5' as a case, I want '05' to match it. If I give you qr/^boo.*boo$/, I want you to match 'booboo' and 'booBOOboo'. If I give you a code reference, I want you to pass the value to the coderef which will return true or false. And, so forth.
  • Options for how matching happens. I might want a switch statement to be case-sensitive or case-insensitive. I might want matches to always be string-matches (in which case '5' and '05' are different) or I might want them to be smart.
  • I want a redo statement in my switch. This is actually very useful in parsing, particularly something like CSV data. Text::xSV basically implements a switch statement with redo as its parsing engine. (Oh, and the cases are primarily regexes.)

Taking a page from Class::MakeMethods, it might be useful to have each case be an arrayref. The last value is the action to take. All others are the case options. If the first value begins with '--', then it's an optional modifier to how to handle the next case option. So, maybe something like:

my $switch = Switch->new( [ '5', sub {} ], # Matches '005' [ '--string-match', '6', sub {} ], # Doesn't match '006', [ qr/floober/, sub {} ] # regex match [ sub { $foo->bar( @_ ) }, sub {} ] # coderef [ 1 .. 3, 8 .. 20, sub {} ] # Multiple cases );

That would be a useful module.

  • In general, if you think something isn't in Perl, try it out, because it usually is. :-)
  • "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"

Replies are listed 'Best First'.
Re^2: Switch/case as a dispatch table with C-style fall-through
by Roy Johnson (Monsignor) on May 12, 2005 at 14:06 UTC
    Actually, the mechanics are important. My objective in this was to address the complaints that switch is just a chain of if-elses: that all the alternatives have to be searched until a match is found. I have implemented it as a dispatch table to eliminate searching. That precludes "smart matching", though. Only strict equivalence can be done this way (ok, anything's possible, but it's not reasonable).

    For more of what you're looking for, I recommend my previous posting, (Revisiting) Smart match in p5. It looks a lot like your example, though I didn't turn it into an object, and I'm not sure there's any advantage to doing so. It will be another flavor to be included in the Case package.

    Caution: Contents may have been coded under pressure.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://456376]
and the questions are moot...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2017-10-22 16:38 GMT
Find Nodes?
    Voting Booth?
    My fridge is mostly full of:

    Results (273 votes). Check out past polls.