1
votes

I am getting a undefined local variable or method error.

class MyClass
  def initialize(my_value, &if_undefine_method)
      @my_value = my_value
      @a = if_undefine_method
   end

  def method_missing(m, *args, &block)
     @a.call
  end

  def my_method_to_call_from_block
     'HELLO'
  end
end

a = MyClass.new("some_value") do
     my_method_to_call_from_block
end

When I call a missing method:

a.a_method_that_does_not_exist

the method_missing is called, but I get an error:

Traceback (most recent call last): 3: from (irb):17 2: from lib/myruby.rb:22:in method_missing' 1: from (irb):16:inblock in irb_binding' NameError (undefined local variable or method `my_method_to_call_from_block' for main:Object)

How do I reference an instance method from the block I pass, so I prevent the error?

1

1 Answers

2
votes

The block isn't part of MyClass, it has its own self which does not have a my_method_to_call_from_block method. Using @a.call from inside a method of MyClass is no different that calling the block anywhere else.

If you want the block to be executed with self set to your instance of MyClass, you need instance_eval:

def method_missing(m, *args, &block)
   instance_eval &@a
end

Consider the difference:

class MyClass
  def initialize(&block)
      @block = block
   end

  def default_self
    @block.call
  end

  def myclass_self
    instance_eval &@block
  end
end


a = MyClass.new do
  p self
end

a.default_self # main

a.myclass_self # <MyClass:0x00007f8da68da348 @block=#<Proc:[email protected]:16>>