gpt4 book ai didi

ruby-on-rails - Ruby 委托(delegate)/代理

转载 作者:数据小太阳 更新时间:2023-10-29 08:24:38 29 4
gpt4 key购买 nike

给定以下代码:

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”的调用委托(delegate)给数组?

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

最佳答案

正如 Linux_iOS.rb.cpp.c.lisp.m.sh 在评论中指出的那样,在这种情况下您应该使用 __send__ 方法,因为 BasicObject 没有定义实例方法发送:

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

BasicObject.instance_methods.grep /send/
# => [:__send__]

BasicObject 的文档可以证明这一点

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-on-rails - Ruby 委托(delegate)/代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8638305/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com