During the previous Dutch Scala Enthusiasts (DUSE) meeting some people mentioned the fuss about the Dynamic trait. Since ‘method missing’ was one of the features I enjoyed in Ruby and Groovy I decided to dig around and create some examples.
But, first of all: the example code in this post works with the latest RC (2.9-RC2) release… and only when the ‘-Xexperimental’ flag is passed to the compiler. Previous versions of 2.9 actually used different names, so this stuff might change while you’re reading this post.
Basically the using the Dynamic trait you can supply an exit-point to the compiler to invoke when a non-existing method is being called on a given object. Some interesting posts have been written about this feature in Ruby. A good overview of what to use the pattern for was written by Ola Bini a while back.
The following patterns caught my imagination in the past:
- Encoding parameters in the method name (heavily used by Active Record -> entity.find_by_name())
- Builders i.e. creating structured data without quote noise. There are various XML and JSON builders in the Groovy and Ruby world using this approach
Let’s see some examples of the above using the Dynamic trait in scala:
ActiveRecord is one of the first examples I came across which really showed me the power of encoding parameters in the method name. It let’s you write queries for your entities as methods:
The column name is extracted from the method and the call is dispatched to a generic find method.
Using the Dynamic trait in Scala we can do something very similar to the above:
There is a lot going on the the code above, but basically it:
- Calls a non-existent method on ParameterInMethodNameExample, namely ‘findByName’
- Both the method name and the arguments are passed to applyDynamic
- I do some parsing of the method name
- Reflectively a suitable target is searched and invoked on the ParameterInMethodNameExample instance
Sure, this is not ActiveRecord yet… but demonstrates the possibilities very well. For something which is called a statically typed language this feels (is?) _very_ dynamic.
I’ve created a very simple builder to demonstrate how that could work:
applyDynamic just keeps appending new path elements to their parent, and using a recursive toString this prints the actual path. Not very useful, but illustrates how something more elaborate could work.
Do we want this?
A lot of people are/will be concerned about the disadvantages features like this bring to a language. I do however think it is a nice piece op equipment in the toolbox. And like other features (operator overloading?): handle with care… powerful tools can do a lot of damage when used incorrectly.