-
Notifications
You must be signed in to change notification settings - Fork 1
Chain
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:
- The actor to which a message is to be sent, or a function which returns an actor.
- A message to be sent to the actor, or a function which returns a message.
- 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".