So far, so good. My quest to learn Scala by virtue of attempting to build a MUD in that language is going pretty well. At this point, I can telnet to the game server, I can log in (albeit without validation or persistence), and in my last post I added the ability for players to be granted commands like ‘who’, ‘cmdsoul’ (to see the command souls assigned to them), ‘broadcast’, etc.

When we learn new programming languages, we always look at the new language through the filter of our past experiences. This isn’t a sign of a bad programmer – this is merely human nature. It’s how we learn and how our brains filter everything we see, do, and hear. As a result, if we approach a new language like Scala from the point of view of someone who has been doing hard-core OOP for the past several years and only tinkering with functional programming – we tend to rely on certain crutches or conventions.

For example, I have an Actor (a Player, to be exact) and that Actor has multiple mix-in traits. One of these traits manages the list of commands currently available for the player. I am exposing the list of commands as a public field so that the Wizard Command Soul can tell wizards which command souls are attached (this ability is supremely helpful for debugging chained command parsing.. trust me..):

var commandSouls: Map[String, CommandSoul] = Map.empty[String, CommandSoul]

And in the Wizard Command Soul, I do a couple of really hideous things in order to display this list of command souls to the wizard:

val cmdIssuer = soulOwner.asInstanceOf[CommandIssuer]
...
cmdIssuer.commandSouls.foreach( ... )

The first problem with this code is that I’m doing a very classic OOP-style typecast. I’m coercing the soul’s owner (the Actor to which the command soul has been attached) to the trait type CommandIssuer. This means that my Wizard Command Soul now has to have explicit knowledge of how I built my application. In short, it needs to know that the CommandIssuer trait is the one that carries a public field named commandSouls.

Allowing other objects unfettered access to a ‘var’ (mutable) field in Scala just seems wrong. It’s certainly not thread-safe and it feels just wrong to me. This blog is about the pursuit of elegant simplicity and this seems neither elegant nor simple.

I could pull out another classic OOP principle: encapsulation, and wrap that var in a function that returns an immutable map:

	def getCommandSouls = {
		val cmdTemp = commandSouls.toMap
		cmdTemp
	}

When you call toMap and assign that value to a val , it automatically gives you an immutable map. This takes care of some of our thread-safety issues and also prevents other people from tampering with the internal list of commands. But, it’s still just a method wrapper and I still don’t like it because I still have to coerce the actor into the CommandIssuer trait/mixin type. If I decide to move the storage of command maps to a different trait during some future refactor, this code will break.

My next thought, then was to send a message to the soul owner (the player) and I would then expect a message back containing the information I need. This is far more Scala-looking than anything I’ve done so far:

	def handleCommandSoul(verb: String, extParams: List[String]) : Boolean = {
		//val cmdIssuer = soulOwner.asInstanceOf[CommandIssuer]
		var string = "\nCurrently Attached Command Souls:\n"
		soulOwner ! QueryCommandSouls
		self.receiveWithin(500) {
			case rep: CommandSoulReply => {
				rep.souls.foreach( mapitem => string += mapitem._1 + " - " + mapitem._2.describe()._2 + "\n")
				soulOwner ! TextMessage(string)
			}
			case TIMEOUT => {
				soulOwner ! TextMessage("Woah, your command issuer is roasted")
			}
			case somethingElse =>
			{
				println(somethingElse)
				soulOwner ! TextMessage("received a bizarro message!")
			}
		}
		true
	}

I’ve got a couple extra guards in there because I’ve never done this before and have no idea what to expect. What I assume is going to happen here is that the looping react pattern matcher I have in the player will eventually get to the partial function in CommandIssuer and handle the request to query the list of command souls. At that point, it will reply to the sender with the information I’m looking for, using this code:

	case QueryCommandSouls => {
		println(sender + " just asked me for the list of command souls!")
                val souls = commandSouls.toMap // Create an immutable copy!! encapsulation FTW
		sender ! CommandSoulReply(souls)
		}

When I compile and run the MUD this time and I type cmdsoul into my telnet client,  I get something entirely unexpected. The message that my receiveWithin(500) pattern match received was QueryCommandSouls! As it turns out, the wizard command soul is attached to the same player (Actor) that has the CommandIssuer trait. So, basically I’m sending myself the QueryCommandSouls message and immediately after that, I start a receive block. In short, I’m catching my own message before the rest of my reactors can see it.

Remember that Actors in Scala are really nothing more than objects backed by a queue (message box) and every message you send to an Actor is really just dumped into the queue and then pulled out of that queue synchronously or asynchronously using pattern matching syntax. So, when I called receive after sending myself the QueryCommandSouls message, I just received the message I sent a nanosecond ago. I need to refactor this some more to make this more asynchronous to allow the player’s reactors to handle things in the right order.

Here’s my new handleCommandSoul function:

def handleCommandSoul(verb: String, extParams: List[String]) : Boolean = {
		soulOwner ! QueryCommandSouls(this)
	}

Note that I had to change the query message into a case class instead of a case object. This is because if I send the message without any parameters, the sender object on the other end will be the player and not my command soul. To get the reply to come back exactly where I want it, I have to pass the object with the message (unless I actually want the player to handle the reply). This is looking much better – it looks much more idiomatic than my previous attempts.

Now I need to handle the reply in a react loop in my act method in the command soul:

def act() : Unit = {
	loop {
		react {
			case rep:CommandSoulReply => {
				var string = "\nCurrently Attached Command Souls:\n"
				rep.souls.foreach( mapitem => string += mapitem._1 + " - " + mapitem._2.describe()._2 + "\n")
				soulOwner ! TextMessage(string)
			}
		}
	}
}

At this point I can compile and run my MUD again and the cmdsoul command works just as it did before (at least from the player’s point of view) but the internal plumbing has been changed so that it now operates in a thread-safe, asynchronous fashion that looks far more like it belongs in Scala than it does in Java.

The whole point of this blog post is, first and foremost, strive for simplicity. My code looked convoluted, complex, and difficult to read. In addition, I knew it wasn’t thread-safe and violated encapsulation rules. I refactored a couple times and still wasn’t happy. With my final solution of asynchronous messaging between two traits attached to a single parent Actor, I am actually pleased with the result.