简体   繁体   中英

Ruby module that delegates methods to an object

I have an AR object called Run that keeps information of when the run was started, ended, disabled, etc. I am trying to create a class Something and want to make it "runnable". So I created a module called Runnable that takes in a run object on initialization. Now say I mix in this module into a class Something . I want the something object to delegate all the methods defined on run to the run object.

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

Now if I do:

run = Run.find(123)
run.start_date # works!
something = Something.new(run)
something.start_date # NoMethodError: undefined method `start_date' for #<Something:0x007fb4a276b0c0>

Any idea what I am missing? Is there a better way of doing what I am trying to do?

在我看来, SimpleDelegator可以实现您在这里寻找的东西。

You have two mistakes:

  • method_missing needs to be an instance method, not a class method
  • @run.send(name, args) should be @run.send(name, *args) . The former results in ArgumentError: wrong number of arguments (given 1, expected 0) when Run#start_date is executed.

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"

Using Forwardable for now

module Runnable
  extend Forwardable
  def_delegator :@run, :start_date, :end_date

  def initialize(run)
    @run = run
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM