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?