ST 4U 318: Sketching Out a CaseStatement Object
Today's Smalltalk 4 You sketches out a case statement object in Smalltalk. Not because this is a great idea; generally, you want to use Polymorphism. However, having been asked about such a thing, we have a sketch of how to do it. If you have trouble viewing it here in the browser, you can also navigate directly to YouTube. To watch now, click on the image below:
If you have trouble viewing that directly, you can click here to download the video directly. If you need the video in a Windows Media format, then download that here.
You can also watch it on YouTube:
Recently, I was asked about Case Statements and Smalltalk - Smalltalk does not have one (nor does it need one, for the most part) - but it makes for a small, interesting example. I had created one of these in VisualWorks years ago, but it ported pretty cleanly into VA Smalltalk (the only real difference being that #new in VA does not send #initialize to the newly created instance). I have verification that the code works as-is in GNU Smalltalk as well - not a surprise, as it's pretty basic stuff. Here's the class definition:
Object subclass: #CaseStatement classInstanceVariableNames: '' instanceVariableNames: 'cases ' classVariableNames: '' poolDictionaries: ''
There's a convenience method to create the first case, and the collection of cases is a collection of associations (where the key is the case, the value is the execution block for that case):
case: aCondition do: aBlock "answer a new instance with initial condition" ^self new case: aCondition do: aBlock
There are a few instance methods to hook up the machinery:
switch: aCondition "execute block previously stored" self switch: aCondition default: [self error: 'No Default Found'] switch: aCondition default: aBlock "execute block previously stored" | association | association := self findOnKey: aCondition. association notNil ifTrue: [(self findValue: association) value] ifFalse: [aBlock value] findOnKey: aCondition "answer association or nil" ^cases detect: [:each | each key = aCondition] ifNone: [nil] findValue: anAssociation "answer the value" ^anAssociation value
You can then see how this kind of thing works:
| caseStatement | caseStatement := CaseStatement case: 1 do: [Transcript show: 'one'; cr]. caseStatement case: 2 do: [Transcript show: 'two'; cr]; case: 3 do: [Transcript show: 'three'; cr]; case: 4 do: [Transcript show: 'four'; cr].
To actually use the statement, you do this kind of thing:
caseStatement switch: 6 default: [Transcript show: 'Could not find case'; cr]. caseStatement switch: 5.
Try that out and see what happens. You can find the code in VRGoodies (Contributed) in VisualWorks, and that code will port cleanly to at least VA and GNU (and I expect Pharo or Squeak as well).
Need more help? There's a screencast for other topics like this which you may want to watch. Questions? Try the "Chat with James" Google gadget over in the sidebar.
Tags: polymorphism, case statement, smalltalk
Enclosures:
[st4u318-iPhone.m4v ( Size: 4364936 )]
Comments
Re: ST 4U 318: Sketching Out a CaseStatement Object
[anonymous] December 7, 2012 17:36:46.802
Would have been nice if you could have listed some cases where a case statement may be legit. Personally, I tend to use case-ish stuff for data parsing where all I have is a string or other raw value and I need to create an instance of some class from it so I can use polymorphism later.
Re: ST 4U 318: Sketching Out a CaseStatement Object
[Bob Nemec] December 10, 2012 8:42:03.461
One place I found myself using case statements was in the UI code (VA in my case). That's where the Smalltalk code is acting more like a conventional program manipulating data structures.