Chapter 19. Dynamic Invocation in Scala
Most of the time, Scala’s static typing is a virtue. It adds safety constraints that are useful for ensuring correctness at runtime and easier comprehension when browsing code. These benefits are especially useful in large-scale systems.
Occasionally, you might miss the benefits of dynamic typing, however, such as allowing method calls that don’t exist at compile time! The popular Ruby on Rails web framework uses this technique very effectively in its
ActiveRecord API. Let’s see how we might implement the same technique in Scala.
A Motivating Example: ActiveRecord in Ruby on Rails
ActiveRecord is the original object-relational mapping (ORM) library integrated with Rails. Most of the details don’t concern us here,1 but one of the useful features it offers is a DSL for composing queries that consist of chained method calls on a domain object.
However, the “methods” aren’t actually defined. Instead, invocations are routed to Ruby’s catch-all for undefined methods,
method_missing. Normally, this method throws an exception, but it can be overridden in classes to do something else.
ActiveRecord does this to interpret the “missing method” as a directive for constructing a SQL query.
Suppose we have a simple database table of states in the United States (for some dialect of SQL):
-- Name of the state.
-- Name of the capital city.
-- Year the state was admitted to the union.