Dice new vs. self class new

Damien Cassou, Stéphane Ducasse and Luc Fabresse http://stephane.ducasse.free.fr

From the Exercise

To support

(DiceHandle new add: (Dice faces: 4); yourself) 
	+ (DiceHandle new add: (Dice faces: 6); yourself)

We defined + as

DiceHandle >> + aDiceHandle
  | handle |
  handle := DiceHandle new.
  self dice do: [ :each | handle addDice: each ]. 
  aDiceHandle dice do: [ :each | handle addDice: each ]. 
  ^ handle

What Is The Difference...

Between

DiceHandle >> + aDiceHandle
  | handle |
  handle := DiceHandle new.

And

DiceHandle >> + aDiceHandle
  | handle |
  handle := self class new.

Let us see....

What If We Create A New Subclass

DiceHandle subclass: MemoDiceHandle
  ....
(MemoDiceHandle new add: (Dice faces: 4); yourself) 
   + (MemoDiceHandle new add: (Dice faces: 6); yourself)
> aDiceHandle

We get a DiceHandle instance back and not a MemoDiceHandle instance!!!

Solution 1: Creating a Hook

DiceHandle >> + aDiceHandle
  | handle |
  handle := self handleClass new.
  self dice do: [ :each | handle addDice: each ]. 
  aDiceHandle dice do: [ :each | handle addDice: each ]. 
  ^ handle
DiceHandle >> handleClass
  ^ DiceHandle

A subclass may redefine handleClass

MemoDiceHandle >> handleClass
  ^ MemoDiceHandle

Solution 1: Creating a Hook

(MemoDiceHandle new add: (Dice faces: 4); yourself) 
   + (MemoDiceHandle new add: (Dice faces: 6); yourself)
> aMemoDiceHandle

We get an instance of the subclass!

But We Can Do Better!

Let us see

Solution 2

DiceHandle >> + aDiceHandle
  | handle |
  handle := self class new.
  self dice do: [ :each | handle addDice: each ]. 
  aDiceHandle dice do: [ :each | handle addDice: each ]. 
  ^ handle

Conclusion

If we define a subclass of DiceHandle, and send the message + to an instance

/