Related

Post navigation

4 thoughts on “Ruby with statement”

This is nice! However, it doesn’t _really_ do what Python’s `with` statement does. I’m not sure about Pascal, but in Python, the `with` statement is used to wrap a context around a block of code. For example, it can be used to make sure resources get cleaned up properly, without requiring the programmer to explicitly clean them up.

For example, this block of Python opens a file, makes the file handle available as `fh`, and automatically closes the file when the block ends:

`fh` was automatically closed after the `with` block ended, because the object that `open` returns has defined two methods: `__enter__` and `__exit__`. All the `with` statement does is, given an object and a block*, calls the object’s `__enter__` method, passes the return value of that to the provided block*, and when the block* ends, calls, the object’s `__exit__` method.

I’m not the best with Ruby, so I won’t embarrass myself writing an equivalent in Ruby, but knowing how powerful Ruby’s metaprogramming facilities are, I’m sure the equivalent functionality is trivial in Ruby.

* I know Python doesn’t really have “blocks” like Ruby has blocks, but it was convenient to refer to the block of code that way.

I did not mean to say that this implementation does what Python’s with does (and I didn’t really know, either). I was merely saying that Python has a with statement.
While it is certainly a cool feature I think it would be confusing in Ruby, since no such convention on ‘enter’ and ‘exit’ methods exist for us. However some of the standard library (e.g. File.open) sometimes provides the option to pass ‘constructor’ methods a block, in which case it will work similarly as your example. For me the biggest benefit of having with in Ruby is to remove some noise when calling multiple methods on the same object (and calling instance_eval directly is a little ugly and longer way of doing it). But I guess in some cases this could also be a violation of tell-don’t-ask, so perhaps with good enough coding practices it might not even make much sense.

Well, returning the object itself is not necessarily desired in this case. Tap is cool, but it does only yield the value as a param into the block, so you don’t get the same kind of behavior as with instance_eval.
Thanks for the comment!