I have the following code:
class A
def self.scope
yield
end
def self.method_added method
self.instance_eval %{
# do something involving the added method
}
end
end
class B < A
scope do
def foo
end
end
end
When the method_added
hook is fired, will the code inside instance_eval
run within the same scope as the method that was added? Or, will it run outside of it?
What are the caveats and gotchas involved within this?
Your scope
method is basically a no-op. When you pass a block to a method that yields, the block is evaluated in the current scope. Observe:
class A
def self.scope
yield
end
end
A.scope { p self }
# main
Since nothing is yielded to the block, and nothing is done with the return value of yield
, any code run in the block will have the same effect run outside the scope
block.
This isn't the case with instance_eval
, however. When instance_eval
runs a block, self
in the block is set to the receiver (rather than whatever self
is in the block's scope). Like this:
class A
end
A.instance_eval { p self }
# A
But note that this means that self.instance_eval { ... }
is also a fancy no-op, because you're changing the block's self
to the same self
outside the block.
So your code is equivalent to this:
class A
def self.method_added method
# do something involving the added method
end
end
class B < A
def foo
end
end