我试图在类上调用proc,但使用继承的类从中访问实例方法。我认为一些模拟代码会更有意义:)
class Bar
def self.foo &block
@foo ||= block
end
def foo; self.class.foo.call(); end
def bar; 'bar'; end
end
class Foo < Bar
foo do
bar
end
end
Foo.new.foo
# NameError: undefined local variable or method `bar' for Foo:Class
我希望能够访问Bar类上的bar
实例方法。使用继承类中的块调用foo类方法的原因是DSL需求的一部分,但任何关于更好设计的建议都将受到赞赏。
块在词法上有作用域,包括self
的值。在定义块的点上,self
是Bar
,而Bar
不响应bar
。您需要在要调用其方法的对象(在本例中是Bar
的实例,而不是Bar
本身)的上下文中评估块。这就是instance_eval
的作用:
class Bar
def self.foo(&block) @foo ||= block end
def foo; instance_eval(&self.class.foo) end
def bar; 'bar' end
end
class Foo < Bar; foo do bar end end
Foo.new.foo
# => 'bar'
请注意,关于instance_eval
的所有常见免责声明都适用:由于您更改了self
方法的值,因此块作者可能期望可用的实例变量将不可用。