The latest Smalltalk-to-Ruby translation in my SBPPRB archive is “Dispatched Interpretation”. It’s one of the bigger ones I’ve tackled so far. I’m not going to go over the whole pattern here; for that you’ll just need to buy a copy of Smalltalk Best Practice Patterns 🙂
However, one potentially interesting snippet is this one:
class Object
def if_false
self
end
end
class TrueClass
def if_true
yield
end
end
class FalseClass
def if_false
yield
end
def if_true
self
end
end
This is another take on Smalltalk-style method-based control flow. Specifically, the following Smalltalk idiom:
aPredicate ifTrue: [ ... ] ifFalse: [ ... ]
The key difference here from our last foray into Smalltalk-style flow control is a special implementation of #if_true on FalseClass, which ignores the given block and instead returns itself. This enables a call to #if_false to be chained onto the #if_true call, and the #if_false defined on FalseClass then yields to its block in order to execute the negative case.
On the flip side, if the initial object is true, then TrueClass‘ #if_true method is hit, which yields to the given block. It returns the result value of the block, which, assuming it is not false, will respond to #if_false with the do-nothing method we defined on Object. There is an obvious bug in the case where the block given to if_true does, in fact, return the false constant. I’ll leave fixing that bug as an exercise to the reader.
Bugs aside, the upshot is a chained call idiom which looks not unlike the Smalltalk keyword argument version:
object.if_true{ puts "true!"}.if_false{ puts "false!"}
As with some of the other Smalltalk-in-Ruby articles, I put this forward as a curiosity. If you really want to use method-based flow control pervasively, Ruby might not be the best language for it.
[boilerplate bypath=”sbpp”]
Lots to be learned from Smalltalk. Pat Maddox posted similar ideas a while back (http://patmaddox.com/blog/smalltalky.html) that I try to use when I can.
I think this: https://gist.github.com/1389177 will do the same thing, but has fewer moving parts? In your example wouldn’t you also want to add the methods on to NilClass?