Skip to content
laforge49 edited this page Nov 27, 2011 · 2 revisions

Code for perming several operations can get deeply nested and ugly. Consider the following:

def ugly(msg: AnyRef, rf: Any => Unit) {
  val simpleActor = new SimpleActor
  simpleActor(Prnt("The answer to everything:")) {
    rsp1 => {
      simpleActor(UltimateAnswer()) {
        rsp2 => {
          simpleActor(Prnt(rsp2))(rf)
        }
      }
    }
  }
}

We can use a simple state machine, Chain, to compose series of operations, where each operation has an actor, a message and a result that can be used in subsequent operations. Once composed, a Chain object can then be passed as a message to an actor for evaluation. Chain has two important methods: op and apply.

The op method is used to add an operation to the chain. It has 3 arguments:

  1. The actor to which a message is to be sent, or a function which returns an actor.
  2. A message to be sent to the actor, or a function which returns a message.
  3. And optionally, a name to which the result is to be bound.

The apply method is used to access an earlier result. It takes a single argument, the name to which the result was bound.

Here then is that ugly code, rewritten using chain:

val chain = new Chain
val simpleActor = new SimpleActor
chain.op(simpleActor, Prnt("The answer to everything:"))
chain.op(simpleActor, UltimateAnswer(), "answer")
chain.op(simpleActor, Unit => Prnt(chain("answer")))

Future(simpleActor, chain)

In the third call to op the anonymous function, Unit => Prnt(chain("answer")), was passed instead of a simple message. This way the call to chain("answer") is delayed until after a result has been bound to "answer".

SimpleChainTest

Chain

Clone this wiki locally