4 ms·
The two mechanisms are not very similar. With the blocks mechanism (if I understand correctly) the resource itself implements a method "execute this code and cl
by praptak 14y ago
The two mechanisms are not very similar. With the blocks mechanism (if I understand correctly) the resource itself implements a method "execute this code and clean up yourself". This only uses the standard mechanisms of the language (i.e. blocks.) The control is with the resource.
Python's 'with' inverts the control - the control is with the language runtime and the resource is passive here. In fact 'with' is a special syntax extension, with calls to hard coded method names (__enter__ and __exit__) done by the Python runtime. The resource itself (or the contextmanager representing it) only implements __enter__ and __exit__ and is passive with regards to this mechanism.
- vidarh 14y ago> With the blocks mechanism (if I understand correctly) the resource itself implements a method "execute this code and clean up yourself". Where the method is doesn't matter, e.g. the (incomplete) example I gave of implementing "with" in Ruby that shows a method that can be defined in the global "main" scope or wherever you want. Some classes implement class-methods to instantiate an object and pass it to a black and free the resource as a convenience, such as File.open, but it could go wherever else. The resource itself most certainly does not need to know a thing about it as long as its API lets you do the cleanup you want/need. > The control is with the resource. The control is with whatever calls yield. Whether that be a method on the global "main" object (closest thing Ruby has to a global, freestanding function) or on the class of the resource itself, or an explicit "begin ... ensure ... end" block if you only need it once. > In fact 'with' is a special syntax extension, with calls to hard coded method names (__enter__ and __exit__) done by the Python runtime. Which is why I gave my example of how I thought "with" would look like in Ruby (as it turns out I missed some exception handling in order for it to be equivalent to the Python version in functionality).
- tsuraan 14y agoWhich is why I gave my example of how I thought "with" would look like in Ruby (as it turns out I missed some exception handling in order for it to be equivalent to the Python version in functionality). What you can't do, though, is express ruby's blocks using python's with statement; ruby is strictly more powerful here. One simple example of this is ruby's fork statement, which runs the code in the block in a process of its own: fork { puts "child" } puts "parent" That will print "child" and "parent" once each, and it works because the fork method has control over the block's execution, so it can choose to only evaluate the block in the child's context. In python, the approximate code would be: with fork(): print 'child' print 'parent' However, python doesn't allow the resource to control block execution, so this code can't work (within standard python; there's a bytecode hack that can make it work, but that's outside the spec). Anyhow, I guess we've diverged pretty hard from the article, but I can never pass up the opportunity to vent against python's with statement.