Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

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

by Animator (Hermit)
on May 13, 2005 at 10:00 UTC ( [id://456652]=note: print w/replies, xml ) Need Help??


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

Here are some others thoughts:

In your current implementation you define the break function in the caller's package, but what if there is already a break function in it?

Wouldn't it be better to allow a user-defined name, and/or return a blessed version of the coderef and make it possible to call the break method on it? (in order to this to work properly you will need to pass the object itself to the code-ref of the eval)

And shouldn't the break function stop the execution of the code? (although this might be rather complicated..., as in adding 'last' to the break sub won't work if the code has it's loop, using die/eval might work but that would be slower...)

And what about implementing next, redo and last?

Where next could mean, jump to the next case statement (that is the fallthru one, possibile with or without ignoring the fallthru variable (if break doesn't return immediatly))

Redo could mean redo the case-coderef. (Updated (old text: entire switch statement, this might be useful when a certain case code-ref modifies the input and wants to re-check it...)

And last could be an alias to break...

By creating your own loop you can figure out which one was called... Some code to demonstrate:

my ($redo, $next, $last)=(0, 0, 1); { my $first = 0; for (0, 1) { if (not $_ and $first++) { $redo=1; $last = 0; last; } if ($_) { $next = 1; $last = 0; last; } main_code(); $last = 0; last; } } $,=" & "; print ($next, $redo, $last); sub main_code { redo; } # replace redo with next and/or last to test

Replies are listed 'Best First'.
Re^2: Switch/case as a dispatch table with C-style fall-through
by Roy Johnson (Monsignor) on May 13, 2005 at 12:42 UTC
    Good things to think about.

    While I was proud of how I got a break() into the mix, it smells more like a trick than a well-designed component of the tool. As you point out, it should really stop execution of the current sub as well as preventing execution of the fallthrough sub, and I don't think I can make it do that.

    If the user had defined a break() sub of his own, it would be unavailable in the switch subs, masked by the one I defined. But outside of that, it would be perfectly functional. If the user wanted to use it in the switch, he'd have to take a reference to it and call that. I thought it was a reasonable compromise, but I think I have a better, break()-less design in mind, now.

    In the K&R book on C, the double-edged sword of fallthrough is addressed. Programmers are encouraged to use it only to apply one code block to multiple conditions, rather than to have one code block fall through to another. That is how I plan to make my case statement operate. Suddenly, there's no more need for break().

    For the exceptional cases where chaining is desired, I will provide a local $Case::this (or $Case::self, whatever...maybe $Case::chain) variable that the user can use for recursing or chaining cases. So instead of introducing new pseudo-keywords (and the compromises they bring), we get less-cluttered, DWIM normal operation, and a flexible facility for doing tricky things if needed. The features you requested would translate thus:
    last return
    next $Case::chain->('specified term'); return
    redo goto &$Case::chain
    I particularly like having an explicit target for fall-through, which specifically addresses the dangers of C-style fall-through. Oh, and I use $_ instead of $_[0] because that's where I think the current term should go.

    I don't think I've designed anything impossible. I won't be able to implement it until next week, though.


    Caution: Contents may have been coded under pressure.

Log In?
Username:
Password:

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

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

    No recent polls found