Ruby with statement

Well, Ruby doesn’t have a with statement (like Python or Pascal do). But Ruby is a cool language, so if you want to have it, you can have it.

module Kernel
def with(object, &block)
object.instance_eval &block
# Simple way to use it
with "Ruby Rocks!" do
puts self
puts size
# More verbose way of using it
with "Ruby" do |s1|
with "Rocks!" do |s2|
puts "#{s1} #{s2}"

view raw
hosted with ❤ by GitHub

Why not 🙂 Enjoy Ruby.

4 thoughts on “Ruby with statement

  1. 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:

    with open('/tmp/test.txt') as fh:
    contents =
    # do stuff with contents
    print(fh) # => error because fh doesn't exist here

    `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.

    • Hey,

      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. 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.

      Cheers and thanks for the comment

    • 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!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s