Ruby on rails 将方法委托给对象的Ruby模块
我有一个名为Run的AR对象,它保存运行开始、结束、禁用等的信息。我试图创建一个类,并希望使其“可运行”。因此,我创建了一个名为Ruby on rails 将方法委托给对象的Ruby模块,ruby-on-rails,ruby,rails-activerecord,metaprogramming,Ruby On Rails,Ruby,Rails Activerecord,Metaprogramming,我有一个名为Run的AR对象,它保存运行开始、结束、禁用等的信息。我试图创建一个类,并希望使其“可运行”。因此,我创建了一个名为Runnable的模块,它在初始化时接收一个run对象。现在假设我将这个模块混合到一个类中。我希望something对象将运行时定义的所有方法委托给run对象 module Runnable def initialize(run) @run = run end def self.method_missing(name, *args) sup
Runnable
的模块,它在初始化时接收一个run对象。现在假设我将这个模块混合到一个类中。我希望something对象将运行时定义的所有方法委托给run对象
module Runnable
def initialize(run)
@run = run
end
def self.method_missing(name, *args)
super unless @run.respond_to?(name)
@run.send(name, args)
end
end
class Something
include Runnable
end
现在如果我这样做:
run = Run.find(123)
run.start_date # works!
something = Something.new(run)
something.start_date # NoMethodError: undefined method `start_date' for #<Something:0x007fb4a276b0c0>
run=run.find(123)
run.start#u date#有效!
某物=某物。新的(运行)
something.start#u date#NoMethodError:for的未定义方法“start#u date”#
知道我错过了什么吗?有没有更好的方法来完成我想做的事情?现在使用可转发的
module Runnable
extend Forwardable
def_delegator :@run, :start_date, :end_date
def initialize(run)
@run = run
end
end
在我看来,a将实现您在这里寻找的目标。您有两个错误:
方法\u缺少
需要是实例方法,而不是类方法
@run.send(name,args)
应该是@run.send(name,*args)
。前者导致ArgumentError:当执行Run#start_date
时,参数数量错误(给定1,预期为0)
类运行
def开始日期
“现在随时”
结束
结束
模块可运行
def初始化(运行)
@跑
结束
def方法_缺失(名称,*args)
超级,除非@run.response_?(姓名)
@run.send(名称,*args)
结束
结束
分类
包括可运行的
结束
run=run.new
run.start\u日期
#=>“随时都可以”
某物=某物。新的(运行)
#=> #
开始约会
#=>“随时都可以”
我考虑过这个问题,但我不能在模块中使用它,对吗?但我不确定您为什么要在这里使用模块。您在其中定义了initialize,这似乎不是一个非常灵活的模块。为什么不使用继承并执行类
?因为我只有一次机会从类继承。一旦我的Something
类继承了Runnable
,它就不能继承其他任何东西。
class Run
def start_date
"Any time now"
end
end
module Runnable
def initialize(run)
@run = run
end
def method_missing(name, *args)
super unless @run.respond_to?(name)
@run.send(name, *args)
end
end
class Something
include Runnable
end
run = Run.new
run.start_date
#=> "Any time now"
something = Something.new(run)
#=> #<Something:0x00000002642100 @run=#<Run:0x0000000266d558>>
something.start_date
#=> "Any time now"