In working on my current and perpetual Squeak project, a roguelike game tentatively titled "The Infernal Tower"[1], I concluded that I could really use a case statement in order to properly handle keyboard input. Even though there are at least two such mechanisms, one of which works without curly brackets, I decided to be trendy and invent my own. I present it here for your perusal:
I implemented the following method in Object:
case: obj do: block self = obj ifTrue: [block value].
It is used as follows:
letter case: $a do: [ stream nextPut: 'Apple'. ];
case: $b do: [ stream nextPut: 'BeBox'. ];
case: $c do: [ stream nextPut: 'Commodore'. ];
...and so on...
case: $z do: [ stream nextPut: 'Zilog'. ].
(I realize that this example could be implemented more easily using a Dictionary. It's just for illustration.)
Advantages: -Looks like the switch/case statements we procedural programmers know and love. -It's very, very simple. -It makes use of blocks and messages to do its thing, just like the standard control structures.
Disadvantages:
-Behaviour is subtly different from what C/Pascal programmers would expect, in that all possibilities are tried rather than just the one that matches the receiver.
-Because of this, it's also slower. I can alleviate (sp?) some of this by making the method return in the block, but that's not always possible.
In addition, I've implemented #case:case:do: (but not #case:case:case:do: or #case:case:case:case:do: yet) to simulate simple fall-through. (#case:case:do evaluates the block if either of its arguments equals the receiver.
I've also implemented #identityCase:do: which uses #== instead of #= to make its comparisons, but that message is somewhat awkward. Perhaps, I should make #case:do: use #== and implement a new method, say #caseEq:do: which uses #=. I suspect it would also make it easier to optimize #case:do: at compile time, should somebody want to implement that.
Now try THAT in C++!
--Chris
[1] Currently 65% vapourware.
Chris, This best implemenation of the case statement is given in the article, 'Smalltalk Case Statements' by Paul Baumann in the July/August 1997 issue of The Smalltalk Report. Baumann's article illustrates the ease of providing support for a case statement, gives examples of their use, and explains why the example case statement is appropiate. I am sending you the code directly. Phil Weichert
Chris Reuter wrote:
In working on my current and perpetual Squeak project, a roguelike game tentatively titled "The Infernal Tower"[1], I concluded that I could really use a case statement in order to properly handle keyboard input. Even though there are at least two such mechanisms, one of which works without curly brackets, I decided to be trendy and invent my own. I present it here for your perusal:
I implemented the following method in Object:
case: obj do: block self = obj ifTrue: [block value].
It is used as follows:
letter case: $a do: [ stream nextPut: 'Apple'. ];
case: $b do: [ stream nextPut: 'BeBox'. ]; case: $c do: [ stream nextPut: 'Commodore'. ]; ...and so on... case: $z do: [ stream nextPut: 'Zilog'. ].
(I realize that this example could be implemented more easily using a Dictionary. It's just for illustration.)
Advantages: -Looks like the switch/case statements we procedural programmers know and love. -It's very, very simple. -It makes use of blocks and messages to do its thing, just like the standard control structures.
Disadvantages:
-Behaviour is subtly different from what C/Pascal programmers would expect, in that all possibilities are tried rather than just the one that matches the receiver. -Because of this, it's also slower. I can alleviate (sp?) some of this by making the method return in the block, but that's not always possible.
In addition, I've implemented #case:case:do: (but not #case:case:case:do: or #case:case:case:case:do: yet) to simulate simple fall-through. (#case:case:do evaluates the block if either of its arguments equals the receiver.
I've also implemented #identityCase:do: which uses #== instead of #= to make its comparisons, but that message is somewhat awkward. Perhaps, I should make #case:do: use #== and implement a new method, say #caseEq:do: which uses #=. I suspect it would also make it easier to optimize #case:do: at compile time, should somebody want to implement that.
Now try THAT in C++!
--Chris
[1] Currently 65% vapourware.
Phil,
This best implemenation of the case statement is given in the article, 'Smalltalk Case Statements' by Paul Baumann in the July/August 1997 issue of The Smalltalk Report. Baumann's article illustrates the ease of providing support for a case statement, gives examples of their use, and explains why the example case statement is appropiate.
I haven't seen the article. Could you briefly summarize what it's all about?!
Thanks, Andreas
Here is some examples from the code. .. !Case class methodsFor: 'examples'!
enumerationTest: anInteger "Answer true if anInteger is included in collection else answer false. This can be combined with other caseIsAny:then: and case:then: statements to test aValue to be one of a combination of discrete values or passed any of several range tests." "Case enumerationTest: 6." "Case enumerationTest: 10."
^anInteger switch caseIsAny: #( 1 3 6 12 16) then: [ true ]; default: [ false ].!
vendLargestAvailableCurrency: unVendedCurrenyValue "Similiar to Baumann's MoneyVendor>>vendLargestAvailableCurrency but modified to not require additional classes or new methods. " "Case vendLargestAvailableCurrency: 5" "Case vendLargestAvailableCurrency: 50" "Case vendLargestAvailableCurrency: 500"
| hasHundred hasFifty hasTwenty hasTen | hasHundred := true. hasFifty := true. hasTwenty := true. hasTen := true. ^unVendedCurrenyValue switch case: [:value | value >= 100 and: [hasHundred]] then: ['vend hundred']; case: [:value | value >= 50 and: [hasFifty]] then: ['vend fifty']; case: [:value | value >= 20 and: [hasTwenty]] then: ['vend twenty']; case: [:value | value >= 10 and: [hasTen]] then: ['vend ten']; default: ['raise out of cash signal']! !
Andreas Raab wrote:
Phil,
This best implemenation of the case statement is given in the article, 'Smalltalk Case Statements' by Paul Baumann in the July/August 1997 issue of The Smalltalk Report. Baumann's article illustrates the ease of providing support for a case statement, gives examples of their use, and explains why the example case statement is appropiate.
I haven't seen the article. Could you briefly summarize what it's all about?!
Thanks, Andreas -- Linear algebra is your friend - Trigonometry is your enemy. +===== Andreas Raab ============= (raab@isg.cs.uni-magdeburg.de) =====+ I Department of Simulation and Graphics Phone: +49 391 671 8065 I I University of Magdeburg, Germany Fax: +49 391 671 1164 I +=============< http://isgwww.cs.uni-magdeburg.de/~raab >=============+
squeak-dev@lists.squeakfoundation.org