Friday, March 29, 2019

ComputedSlots in Pharo

In Pharo 8 it is now possible to use ComputedSlots. Beside the regular instance variable (slots) we add a computed slot with a block.

Let's assume I would like to implement a Person class with a name and firstName but also get a fullName.

Object subclass: #Person
 slots: { #name. #firstName. #fullName => ComputedSlot with: [ :obj | obj firstName asString , ' ' , obj name asString ] }
 classVariables: {  }
 package: 'Simple-Example'

so when you test
 
|p|
p := Person new.
p name: 'Adams'.
p firstName: 'Douglas'.
p fullName 
 

it would return the full name 'Douglas Adams'.

When you now add an additional class side method #firstName:name: like

firstName: firstName lastName: lastName

 ^(self new)
  firstName: firstName;
  name: lastName;
  yourself

you can simply write with our small english like DSL:

 (Person firstName: 'Douglas' lastName: 'Adams') fullName

to get the same result.

For sure we could have implement the getter method #fullName like this:

fullName

 ^self firstName asString , ' ' , self name asString

to achieve the same - but a computed slot shows up really in the inspector as if it would be a real variable and is recomputed if you for instance would change the name or firstName.