. .


ST 4U 318: Sketching Out a CaseStatement Object

December 7, 2012 12:33:47.791

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:

Case Statement.

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].
	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: , ,

[st4u318-iPhone.m4v ( Size: 4364936 )]

posted by James Robertson

 Share Tweet This