The Device
Thursday, February 22nd, 2007It is the first time I am falling for a dumb useless thing like this.
But yes, I would spend some money towards this rig.
It is the first time I am falling for a dumb useless thing like this.
But yes, I would spend some money towards this rig.

Umlaut your varialbles for a cool heavy metal effect. It makes code better.
Thanks Erik.
Let’s consider this piece of neat meta-programming sugar. We have two Rails Models, User and Role with Migrations defined as:
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.column 'role_id', :integer
t.column 'email', :string
end
end
def self.down
drop_table :users
end
end
class CreateRoles < ActiveRecord::Migration
def self.up
create_table :roles do |t|
t.column 'name', :string
end
end
def self.down
drop_table :roles
end
end
Let’s imagine that we have three types or Role, Root, Administrator and Customer. We want the Users to know which Role they belong to. Supposing Role looks as simple as:
class Role < ActiveRecord::Base has_many :users end
… a perfectly acceptable implementation of User could be:
class User < ActiveRecord::Base
belongs_to :role
def root?
self.role.name == 'root'
end
def administrator?
self.role.name == 'administrator'
end
def customer?
self.role.name == 'customer'
end
end
Now, I get an uneasy feeling every time I see similar looking code repeated more than once and, thanks to Ruby’s monkey code remedy nature, I can achieve the same result by writing the above as:
class User < ActiveRecord::Base
belongs_to :role
Role.find(:all).each do |role|
define_method("#{role.name}?") do is? role.name end
end
private
def is? role_name
self.role.name == role_name
end
end
There’s another advantage to this approach. Come a time when I need to add more Role definitions, I will not have to worry about User, in terms of writing code for it to comply with the changes to Role.
But all this begs the question: Is every body better off with me trying to be clever and not doing the straightforward thing any ol’ dev could grasp in a second, even though I’m saving the world (and my app) a few bytes?
To be honest, I’m not particularly fond of the idea of compromising code effectiveness or elegance in order to accommodate mediocre developers. I find that to be a pessimistic strategy that could ultimately act against the benefit and integrity of the solution.
Having said that, being part of larger teams exponentially increases one’s responsibility towards the possible maintainers of their code, so I don’t feel I’m 100% right on the above declaration.
Callbacks are a great way of keeping different Objects loosely coupled, without having to hard code direct references or calls between collaborators. Languages that support blocks/closures offer an elegant and flexible alternative to approaches of the Java interface style.
EventDispatcher := Object clone do(
listeners := Map clone
subscribe := method(event, callback,
listeners hasKey(event) ifFalse(listeners atPut(event, List clone))
listeners at(event) append(callback)
)
notify := method(event, args,
if(listeners hasKey(event),
listeners at(event) foreach(callback, callback call(args))
)
)
)
The above EventDispatcher Object comes with two methods, subscribe and notify. The most interesting bit is how subscribe maps registered callbacks to their respective events. Upon notification (the notify method), every callback registered with the given event will execute.
factory := EventDispatcher clone do(
produceWidget := method(color,
"I am creating a #{color} widget" interpolate println
notify("new_widget", color)
)
)
The code above signifies that every time the Factory produces a Widget, it will notify any listener interested in monitoring the production of new widgets. Interestingly, the factory knows nothing about listeners. IO scores some extra, not visible in this example, points by supporting Multiple Inheritance (sounds scary, but it’s closer to Ruby’s Mixins, rather than C++). Any ol’ Object can have the EventDispatcher’s functionality available by adding EventDispatcher to it’s list of Protos.
Following is an example Listener that registers its intentions of being notified about the creation of new Widgets with the Factory.
widgetCounter := Object clone do(
counts := Map clone
factory subscribe("new_widget", block(color,
counts hasKey(color) ifFalse(counts atPut(color, 0))
counts atPut (color, counts at(color) nextInSequence)
"#{counts at (color)} #{color} widget(s)
created since I started listening" interpolate println
)
)
)
Now, if the factory produces a few Widgets…
factory produceWidget("blue")
factory produceWidget("green")
factory produceWidget("blue")
factory produceWidget("blue")
factory produceWidget("red")
widgetCounter keeps track of the them, in respects to their colors…
~/Desktop $ io EventDispatcher.io I am creating a blue widget 1 blue widget(s) created since I started listening I am creating a green widget 1 green widget(s) created since I started listening I am creating a blue widget 2 blue widget(s) created since I started listening I am creating a blue widget 3 blue widget(s) created since I started listening I am creating a red widget 1 red widget(s) created since I started listening
The example was inspired and is a port of the recipe described in chapter 7.11 Coupling Systems Loosely with Callbacks found in O’Reilly’s Ruby Cookbook by Lucas Carlson and Leonard Richardson
I probably never noticed this before because I never happened to gem update without sudo prefixing the command on the iBook. I just accidentally did, though, and lo the - not so - informative message:
ERROR: While executing gem ... (NoMethodError)
undefined method `source_index' for #<Hash:0x283d464>
Not great…
What can I say?.. Spot on… (via Juan)
