May 09, 2021 CoffeeScript
You want to call multiple methods on an object, but you don't want to reference the object every time.
Returns the thiss object after each chain call
class CoffeeCup
constructor: ->
@properties=
strength: 'medium'
cream: false
sugar: false
strength: (newStrength) ->
@properties.strength = newStrength
this
cream: (newCream) ->
@properties.cream = newCream
this
sugar: (newSugar) ->
@properties.sugar = newSugar
this
morningCup = new CoffeeCup()
morningCup.properties # => { strength: 'medium', cream: false, sugar: false }
eveningCup = new CoffeeCup().strength('dark').cream(true).sugar(true)
eveningCup.properties # => { strength: 'dark', cream: true, sugar: true }
The jQuery library uses a similar method to return the selector object from each similar method, and in subsequent methods modifies the object by adjusting the selection range:
$('p').filter('.topic').first()
For our own objects, a little metaprogramming can automatically set up the process and clearly state the intention to return the thisis.
addChainedAttributeAccessor = (obj, propertyAttr, attr) ->
obj[attr] = (newValues...) ->
if newValues.length == 0
obj[propertyAttr][attr]
else
obj[propertyAttr][attr] = newValues[0]
obj
class TeaCup
constructor: ->
@properties=
size: 'medium'
type: 'black'
sugar: false
cream: false
addChainedAttributeAccessor(this, 'properties', attr) for attr of @properties
earlgrey = new TeaCup().size('small').type('Earl Grey').sugar('false')
earlgrey.properties # => { size: 'small', type: 'Earl Grey', sugar: false }
earlgrey.sugar true
earlgrey.sugar() # => true