Taking a page from RSpec: block-lifetime methods?

16 views
Skip to first unread message

John Feminella

unread,
Apr 25, 2014, 10:22:38 AM4/25/14
to rs...@googlegroups.com
I'm asking this question here because it occurred to me that RSpec seems to do what I want, but I can't figure out how to replicate this effect in my own code. 

Inside the body of a class, I'd like to pass a block to a method called `with`. For the lifetime of the block, I would like a `with_value` method to be available. Otherwise, everything inside the block should behave as if it were outside the block.

Here's an example:

    class C
      extend M
    
      with "some value" do
        do_something_complicated
        do_something_complicated
        do_something_complicated
      end
    end

We can _almost_ get this with:

    module M
      def with(str, &block)
        Object.new.tap do |wrapper|
          wrapper.define_singleton_method :with_value do  # Here's our with_value
            str                                           # method.
          end
        end.instance_eval &block
      end
    
      def do_something_complicated                        # Push a value onto an
        (@foo ||= []).push with_value                     # array.
      end
    end

but there's a problem: since we're evaluating the block passed to `with` inside the context of a different object, `do_something_complicated` isn't available.

What's the right way to pull this off? Any suggestions?

Myron Marston

unread,
Apr 28, 2014, 1:20:21 AM4/28/14
to rs...@googlegroups.com
RSpec doesn't do anything fancy with blocks....just calls them and/or `instance_eval`s them occasionally.  It's not clear to me which part of RSpec you are thinking of? 
Reply all
Reply to author
Forward
0 new messages