0

I want to extend the functionality of a method asdf at runtime. A method append_asdf should allow modifying the method more easily.

I understand how to call the previous method but the private variable @b evaluates to nil inside the block used to specify the additional behaviour - if passed through the wrapper. It works as expected when passed to class_eval directly (which is not what I want).

Why?

class A
  def initialize
    @b = "144"
  end

  def asdf
    puts "12"
  end

  def self.append_asdf(&n)
    m = instance_method(:asdf)
    define_method(:asdf) { 
      m.bind(self).call
      n.call
    } 
  end
end

a = A.new

p = proc {
  puts @b
}

The proc p is used here to drive home the point that it doesn't depend on the block. It behaves the same as a literal.

This doesn't work:

A.append_asdf(&p)
a.asdf
=>
12

Note the empty line. The same proc used here evaluates as expected:

A.class_eval {
  define_method(:asdf, p)
}
a.asdf
=>
144

1 Answer 1

1

You need to evaluate that block in the proper context. In other words:

instance_eval(&n)

Instead of a regular call.

Sign up to request clarification or add additional context in comments.

1 Comment

i thought i already did that - and now i feel very stupid... :-D thanks for your time

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.