I cleaned up some old VisualWorks code I had from Ernest Micklei and published it to the Cincom Public Repository. Watch out for a "Teachable" package.
It's another nice example how powerfull Smalltalk really is. It's an implementation of a Teachable class who's instances can be teached to respond to messages. It's usefull for creating mocks who should behave like other objects (for instance inside of a test case) without actually implementing a real mock class. Here is an example how it can be used:
|teachable|
teachable := Teachable new.
teachable
whenSend: #help return: 'ok';
whenSend: #doit evaluate: [1 inspect];
acceptSend: #noDebugger;
whenSend: #negate: evaluate: [:num num negated].
After teaching the object we can use it as if it had a normal implementation in a class:
teachable help. "this will return the string 'ok'"
teachable doit. "this will open the inspector on the SmallInteger 1"
teachable noDebugger. "this will accept the send of #noDebugger and return the teachable"
teachable negate: 120 "this will return -120"
A Squeak version of the code can be found here.
I see you haven't posted much on Teachable lately (based on a search of your blog and Google), but I just tried using it and it's quite interesting!
ReplyDeleteMy first comment was: "Oh, it'd be very interesting if there were a way to essentially create new variables in the object, not just methods.".
But of course, there is any easy way to simulate this!
----------------------------
fighter := Teachable new.
variables := Dictionary new.
fighter whenSend: #variables return: variables.
fighter variables at: #health put: 1.
fighter whenSend: #health evaluate: [fighter variables at: #health].
fighter whenSend: #health: evaluate: [:num| fighter variables at: #health put: num.].
fighter health.
fighter health: 10.
----------------------------
This is just a sample and can probably be cleaned up some, but you store the object's "variables" inside a dictionary, then have a way to return that dictionary (and thus add and remove new variables).
You can then create getter/setter methods that access the given "variable" just as a normal object. To an outside user, this will end up looking *exactly* the same (as if you had an instance variable in the traditional method, along with getter/setter).
So, anyway, yes, thank you for this! Very interesting. :)
- Alex
I see you haven't posted much on Teachable lately (based on a search of your blog and Google), but I just tried using it and it's quite interesting!
ReplyDeleteMy first comment was: "Oh, it'd be very interesting if there were a way to essentially create new variables in the object, not just methods.".
But of course, there is any easy way to simulate this!
----------------------------
fighter := Teachable new.
variables := Dictionary new.
fighter whenSend: #variables return: variables.
fighter variables at: #health put: 1.
fighter whenSend: #health evaluate: [fighter variables at: #health].
fighter whenSend: #health: evaluate: [:num| fighter variables at: #health put: num.].
fighter health.
fighter health: 10.
----------------------------
This is just a sample and can probably be cleaned up some, but you store the object's "variables" inside a dictionary, then have a way to return that dictionary (and thus add and remove new variables).
You can then create getter/setter methods that access the given "variable" just as a normal object. To an outside user, this will end up looking *exactly* the same (as if you had an instance variable in the traditional method, along with getter/setter).
So, anyway, yes, thank you for this! Very interesting. :)
- Alex