Ruby委托/代理

时间:2011-12-26 18:46:32

标签: ruby-on-rails ruby design-patterns delegates ruby-1.9.2

给出以下代码:

class ArrayProxy < BasicObject
  def initialize
    @array = []
  end

  def foo
    puts 'foo'
  end

  def method_missing(*args, &block)
    @array = @array.send(*args, &block)
  end

  def self.method_missing(*args, &block)
    new.send(*args, &block)
  end
end

为什么要将'foo'的调用委托给数组?

ruby-1.9.2-p290 :018 > ArrayProxy.new << 1
 => [1] 
ruby-1.9.2-p290 :019 > ArrayProxy << 1
 => [1] 
ruby-1.9.2-p290 :020 > ArrayProxy.new.foo
foo
 => nil 
ruby-1.9.2-p290 :021 > ArrayProxy.foo
NoMethodError: undefined method `foo' for []:Array

3 个答案:

答案 0 :(得分:6)

正如评论中提到的Linux_iOS.rb.cpp.c.lisp.m.sh,在这种情况下你应该使用__send__方法,因为BasicObject没有定义实例方法{{1} }:

send

这也可以通过BasicObject的文档来证明。

Object.instance_methods.grep /send/ # => [:send, :public_send, :__send__] BasicObject.instance_methods.grep /send/ # => [:__send__] 类中缺少send实例方法会产生以下调用链:

BasicObect

答案 1 :(得分:1)

使用Ruby标准库工具可能更有意义,而不是自己滚动?

Delegator class。 (我指的是1.9.3文档,但该类也存在于1.8.x中)。

答案 2 :(得分:0)

method_missing的签名是method_sym, *args, &block

我认为它正在被发送到数组,因为你在类级new声明中调用method_missing(它实例化一个新的ArrayProxy)并在返回值上调用send。 /德尔>

关于为什么要将@array设置为@array.send(*args, &block)的实例级别声明中的method_missing的返回值,我有点困惑。

编辑:这是一种奇怪的行为。希望将:foo发送到ArrayProxy的实例来打印foo,而不是通过@array将调用委托给method_missing