2

Is there any way of changing the behavior of particular instances of a class without affecting the rest of the instances (i.e., they still behave according to the behavior of the class)?

For instance, I would like the instance a to have a different way of printing itself than the instance b in the following example.

Let's suppose I have a class MyClass, which responds to name, with the following printing service:

MyClass>>printOn: aStream
    aStream
        nextPutAll: self class; 
        nextPutAll: ' instance named ';
        nextPutAll: self name`

Then if I create an instance a, I have the following:

a := MyClass new name: 'a'.
a printString -> 'MyClass instance named a'

Now I would like an instance b to print only its name without affecting the way a prints itself.

b := Object new name: 'b'.
b printString -> 'b'
Leandro Caniglia
  • 14,495
  • 4
  • 29
  • 51
  • "But both b and a are instances of MyClass. That is the reason they talk about "instance behavior", because instances of the same class have different behavior. And the interest of instance specific behavior is, for instance, to use it while debugging, without changing the behavior of other instances." @CarlosE.Ferro "But both b and a are instances of MyClass" Well that is hard to guess when the code is: `b := Object new name: 'b'.`. With the debugging it makes sense - you want to change the value of current instance and see what it implies. – tukan Sep 14 '18 at 07:36

1 Answers1

2

Bee Smalltalk supports instance specific behavior. This means that it is easy to tell any instance of your class how to respond to any given message.

In your case, the easiest way to get what you want is by evaluating

b answerTo: #printString with: 'b'

In fact, this will install an instance specific method in b's behavior representing the method

printString
  ^'b'

but bound only to b and not to other instances of MyClass, which will still use the #printOn: method you defined.

An even better approach would not hardcode 'b' and will instead refer to b name. For doing this you should evaluate:

b answerTo: #printString evaluating: [b name].

This is better because if you rename b so its name is now 'b2', the former implementation of #printString will keep answering 'b', while the latter will answer with 'b2'. In other words, this will install the method

printString
  ^b name

only to b (and keep other instances untouched).

Finally, if you want this behavior to be temporary rather than permanent you should evaluate:

b answerTo: #printString evaluationg: [b name] while: aBlock

where aBlock stands for the block of code that you want to execute and during which your instance needs to have the said specific behavior attached to #printString.

Leandro Caniglia
  • 14,495
  • 4
  • 29
  • 51
  • I see you have deep understanding of Bee Smalltalk :). Congratulation on releasing it to github! (http://beesmalltalk.org/) – tukan Sep 22 '18 at 09:41
  • @tukan many thanks. Not there yet though. There will be something to download in a few days. – Leandro Caniglia Sep 22 '18 at 18:15
  • As written on your pages it still is not physically there but you are working on it, still it is a good news. Don't hurry, it it better to do something properly than fast. – tukan Sep 22 '18 at 18:18
  • Out of curiosity, is there any schedule when Bee will be out? I'm keen on trying new smalltalk :). – tukan Oct 16 '18 at 08:08
  • @tukan Yes, a *technical preview* will be available in a week or two. – Leandro Caniglia Oct 16 '18 at 11:17