3

Rubyで委任を使用したいのですが、ターゲットオブジェクトが呼び出すすべてのメソッドに応答することを保証できません。デフォルトの動作で委任を定義できますか?

例えば

class DummyPresenter
  delegate :name, :age, :to => :@content, :default => nil
  def initialize(content)
    @content = content
  end
end

class Student
  def name
    "name"
  end
end    

> DummyPresenter.new(Student.new).age # => nil
> DummyPresenter.new(Student.new).name # => "name"

さて、上記の例は次のようになります。

NoMethodError:
   undefined method `age' for #<Student:0xa121212>
4

4 に答える 4

4
def method_missing(method, *args)
  if @content.respond_to? method
    @content.send method, *args
  else
    #your default behaviour (or super)
  end 
end

また、DelegateClassを使用して、同じトリックを実行できます。

于 2012-06-25T12:01:01.850 に答える
2

メソッドを元のオブジェクトに委任する最も簡単な方法は、SimpleDelegator(stdlibに含まれています)を使用することです。

class Presenter < SimpleDelegator

  def initialize model
    super model
  end

  def foo
    'bar'
  end
end

class Person
  def bam
    'baz'
  end
end

person = Person.new
presenter = Presenter.new Person

presenter.foo # => 'bar'
presenter.bam # => 'baz'

ドキュメントから:

SimpleDelegatorクラスは、サポートされているすべてのメソッド呼び出しをコンストラクターに渡されたオブジェクトに委任する手段を提供します

于 2014-02-21T21:33:49.483 に答える
0

最後に私はそれを使用してそれをしましたdefine_method

class DummyPresenter

  @@delegated_methods = [:name, :age]
  @@delegated_methods.each do |method|
    define_method(method) do
      return @content.try(method) if @content.respond_to?(method)
      nil
    end
  end

 def initialize(content)
   @content = content
 end

終わり

于 2012-06-25T12:51:18.160 に答える
0

デリゲートを使用せず、このように手動で実行するのはどうですか?

class DummyPresenter
  def initialize content; @content = content end
  def name; @content.respond_to?( :name ) ? @content.name : dflt_name end
  def age; @content.respond_to?( :age ) ? @content.age :dflt_age end
  def to; @content.respond_to?( :to ) ? @content.to :dflt_to end
  def dflt_name
    nil # or whathever code
  end
  def dflt_age; nil end
  def dflt_to; nil end
end

そうでなければ、デリゲートメソッドを再プログラムする必要があると思います...

于 2012-06-25T11:49:04.127 に答える