Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Ruby委托/代理_Ruby On Rails_Ruby_Design Patterns_Delegates_Ruby 1.9.2 - Fatal编程技术网

Ruby on rails Ruby委托/代理

Ruby on rails Ruby委托/代理,ruby-on-rails,ruby,design-patterns,delegates,ruby-1.9.2,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)

给定以下代码:

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
class ArrayProxy
为什么要将对“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
ruby-1.9.2-p290:018>ArrayProxy.new[1]
ruby-1.9.2-p290:019>ArrayProxy[1]
ruby-1.9.2-p290:020>ArrayProxy.new.foo
福
=>零
ruby-1.9.2-p290:021>ArrayProxy.foo
NoMethodError:[]的未定义方法“foo”:数组

缺少
方法的签名是
方法符号、*args和block

我认为当您在类级
方法\u missing
声明(实例化一个新的ArrayProxy)中调用
new
并在返回值上调用send时,它被发送到数组

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


编辑:这是一种相当奇怪的行为。希望将
:foo
发送到
ArrayProxy
的实例以打印foo,而不是通过
method\u missing
将调用委托给它的
@array
,正如Linux\u iOS.rb.cpp.c.lisp.m.sh在这种情况下应该使用
\u send\u
方法所指出的那样,由于
BasicObject
未定义实例方法
send

Object.instance_methods.grep /send/
# => [:send, :public_send, :__send__] 

BasicObject.instance_methods.grep /send/
# => [:__send__]
这也可以通过文档来证明

BasicObect
类中缺少
send
实例方法会导致以下调用链:

# initial call
ArrayProxy.foo

# there's no class method 'foo', so we go to class 'method_missing' method
ArrayProxy.method_missing :foo

# inside class 'method_missing' we delegate call to new instance using 'send'
ArrayProxy.new.send :foo

# there is no instance method 'send' in ArrayProxy class (and its parent class
# BasicObject) so instance 'method_missing' is called
ArrayProxy.new.method_missing :send, :foo

# instance 'method_missing' delegates call of 'send' method to @array
@array.send :send, :foo

# that is unfolded into regular call of 'send' on @array object
@array.send :foo

# and finally 'foo' is called for @array object
@array.foo
# => NoMethodError: undefined method `foo' for []:Array   

也许使用Ruby标准库工具比使用自己的工具更有意义


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

在代码中尝试
\uuuuuuu发送
。这也许可以。确实可以,从文档“如果名称send与obj中的现有方法冲突,您可以使用send。”中可以看出,“foo”不是Object中的方法吗?有人能澄清一下接受的答案吗?顺便说一句,你为什么要在
方法中重新分配
@array
。如果使用
Delegator
或将其子类化,则不会委派
class
等方法
BasicObject
的最小方法集允许您创建一个对象,该对象可以在
Delegator
允许的更多场景中“替代”原始对象。