Ruby 如何基于类动态定义模块方法';实例变量?
我有以下课程:Ruby 如何基于类动态定义模块方法';实例变量?,ruby,Ruby,我有以下课程: class Foo include BaseFoo attr_reader :with_context def initialize(with_context: %i[bar baz]) @with_context = with_context end def call puts bar # Should return 'lorem ipsum' puts baz # Should return 'lorem ipsum' e
class Foo
include BaseFoo
attr_reader :with_context
def initialize(with_context: %i[bar baz])
@with_context = with_context
end
def call
puts bar # Should return 'lorem ipsum'
puts baz # Should return 'lorem ipsum'
end
end
如何在模块BaseFoo
中根据的值和上下文动态定义方法
不幸的是,这不起作用,因为模块不知道上下文是什么。
而是让你大致了解需要实现的目标。伪代码:
module BaseFoo
with_context.each |context|
define_method context do
'lorem ipsum'
end
end
end
基本上,BaseFoo
应该具有以下公共方法:
def bar
'lorem ipsum'
end
def baz
'lorem ipsum'
end
如果不与模块进行实际交互,就无法真正做到这一点。当一个模块包含在其包含在类中时,该类会将该模块放置在类的祖先链上,并在该模块上触发module#included
回调
由于这种情况发生在类级别,因此除非您实际调用实例方法,否则无法访问实例的上下文。在这种情况下,self
是包含模块的类的实例:
module BaseFoo
def extend_base_foo
with_context.each do |context|
BaseFoo.module_eval do
define_method context do
'lorem ipsum'
end
end
end
end
end
class Foo
include BaseFoo
attr_reader :with_context
def initialize(with_context: %i[bar baz])
@with_context = with_context
extend_base_foo
end
def call
puts bar # Should return 'lorem ipsum'
puts baz # Should return 'lorem ipsum'
end
end
但老实说,你到底为什么要这么做?创建一个Foo实例实际上会在模块本身上定义这些方法,这意味着它们包含在每个Foo实例中:
Foo.new(with_context: [:x, :y])
Foo.new.x # loren ipsum - big WTF moment
如果确实要执行类似操作,请创建一个匿名模块并使用它扩展实例:
class Foo
def initialize(with_context: %i[bar baz])
m = Module.new do
with_context.each do |context|
define_method(context) do
'lorem ipsum'
end
end
end
self.extend(m)
end
def call
puts bar # Should return 'lorem ipsum'
puts baz # Should return 'lorem ipsum'
end
end
您的第一个示例不起作用Foo.new.call
返回扩展\u base\u Foo中的块:为BaseFoo:Module调用私有方法define\u method(NoMethodError)
我在ruby 2.7.0p0(2019-12-25修订版647ee6f091)中运行了它。它可能与版本有关。可能使用BaseFoo.module\u eval do。。。结束
。