A recent discussion in the GOOS’ group has lead me to consider different ways to compose objects in Ruby. Specifically, as module inclusion seems to be the favored approach for adding stuff to classes in Ruby, I’ve became interested in finding a more flexible idiom for this.
The objective, therefore, is to define an instance variable in a module and be able to have it injected in instances of some class. Since I’m not that familiar with Ruby yet, I’m forced to turn to other languages for inspiration. A possible solution in Scala, presented below, is kind of intuitive.
Let’s start defining a simple trait Lightsource
.
The goal is to have a instance of a class implementing this trait injected in every instance of the class Room
below.
The injection can be performed by mixing-in the Room
class with traits designed to provide a Lightsource
. For example:
The actual composition reads nicely:
If the fluorescent lamp is unsatisfactory, an alternative implementation can be provided:
And I will stop at this point. Although there is opportunity for improvement, the implementation is satisfactory enough for me.
Having succeeded at the Scala front, we can tackle the same issue using Ruby. Here, we find ourselves both unable and not required to declare interfaces, so we move directly to the definition of our Room
class.
The next step is to define a module responsible for providing an @lightsource
object to instances of the Room` class. For instance:
Alternatively:
The actual composition does not read so nicely, but surely it can be improved by some sort of DSL. Being lazy, I’ll skip that, though:
Now, I’m suppose that this approach is not really within Ruby’s orthodoxy, but I found it interesting nevertheless. Also, it surprised me that the Scala version is both cleaner and smaller than the Ruby version, while still providing the safety advantages of the static typing.