Question

Am trying to do the following:

class Tester
  def some_test
    Proc.new do
      def prep_test
      end

      def do_test
      end

      def pass?
      end
    end
  end

  def another_test
    Proc.new ..
      ...
    end
  end

  # tests are mapped in array_of_tests

  def run
    array_of_tests.each do |t|
      t.call.prep_test
      t.call.do_test
      t.call.pass?
    end
  end
end

Tester.new.run

But when I start trying to execute each test t, I get something like:

NoMethodError: undefined method `prep_test' for nil:NilClass

In experimenting, I found that this worked:

def test3
  Proc.new do
    def prep
      "running test3: prep"
    end

    def run
      "running test3: run"
    end

    def verify
      "running test3: verify"
    end
  end
end

t = test3
t.call.prep
t.call.run
t.call.verify

But this wasn't inside a class.

What am I missing to reference the nested methods inside some_test to make Tester.new.run work?

Was it helpful?

Solution

Doh!

def homer
  Class.new do
    def beer
      puts 'mmmm beer'
    end

    def donuts
      puts 'aaaauugggh dooooooooonuts!'
    end
  end    
end

homer.new.beer

If you need to pass any variables, do it the old fashioned way.

The Tester methods are outside the scope of the anonymous class you have generated.

But what you can do is use instance variables to have a reference to tester.

class Scenario
  def test3
    Class.new do
      attr_reader :environment
      def initialize environment
        @environment = environment
      end

      def run
        environment.blah
      end
    end
  end
end

scenario = Scenario.new
scenario.test3.new(scenario).run

OTHER TIPS

This will also work

class Tester
  def some_test
    Proc.new do
      def Object.prep_test
      end

      def Object.do_test
      end

      def Object.pass?
      end
    end
  end
end

Just to clarify what's going on in your two examples; when you execute the Proc it defines the methods on whatever class happens to be executing it. So in the first example, it defines them on the Tester class. In the second example, it defines them on Object. The second example only works because the NilClass class inherits from Object, so even though the Proc is returning a nil, you can still call those methods on it.

Basically, you can't store methods in a Proc like that. The fact that it worked in the second example is a total fluke.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top