The emphasis for the final day of Ruby was on metaprogramming using open classes and mixins. So without further ado, here's a CSV reader that provides a mixin that lets you access the values of a CSV file using dynamic properties (Whee!):
i=rand(10)puts"I'm thinking of a number x ∈ [0,9]. Can you guess it?"whiletruedoprint">> "guess=gets.to_ibreakifguess==iputs"Too low."ifguess<iputs"Too high."ifguess>iendputs"Good job :-)"
(I may have known a little bit of Ruby before I started ;-).
My previous implementation of the with_statement in ruby had one major flaw: It allowed only a single context manager per with block. While effective, it leads to cluttered code, like the following:
Effective, but it isn't as clear as it could be and introduces more nesting than is really necessary. This coupled with my desire to explore varargs methods and blocks in ruby has lead me to a more robust implementation that can take an arbitrary number of managers as a parameter.
The preceding implementation is more complex than the original. In addition to introducing "star magic"1, it relies on recursive creation of begin-ensure blocks which complicates exception handling; however, this implementation allows for such beautiful usage as:
Should a manager's exit method raise an exception, that exception will supersede any exception raised within the block, though it will not interfere with exiting other managers.
An implementation and unittests are available in a Mercurial repository. The implementation can be retrieved as follows:
hg clone http://hg.crimzon.ath.cx/with_statement
Both the implementation and unittests are licensed under the MIT license.
One of the things that I do enjoy about Ruby is the ability to use blocks to synthesize control structures that may be missing. For instance, I'm a big fan of python's with statement. Through a combination of guerilla patching and blocks, the with statement can easily be added to the ruby language as a library.