如何使用ForwardableModule将类方法委托给Ruby中的另一个对象



我想将Bar上的一个类方法委托给Foo类的一个实例,但我无法使委托生效。委托的方法都没有抛出错误,getter只返回nil。以下是我的代码:

class Foo
  attr_reader :worksheet_id, :access_token
  def configure worksheet_id: raise, access_token: raise
    @worksheet_id = worksheet_id
    @access_token = access_token
  end
end
class Bar
  class << self
    extend Forwardable
    def_delegators Foo.new, :configure, :worksheet_id, :access_token
  end
  configure worksheet_id: 1, access_token: 2
end

以下是我想做的事情。

Bar.worksheet_id # => returns nil, should be 1.
Bar.access_token # => returns nil, should be 2.

我做错了什么?

def_delegator方法家族的第一个参数是SymbolString(或实现to_s的任何其他参数),表示访问委派目标的"访问器"。委派的目标本身是而不是

所以,像这样的东西会起作用:

class Bar
  class << self
    extend Forwardable
    def_delegators :@foo, :configure, :worksheet_id, :access_token
  end
  @foo = Foo.new
  configure worksheet_id: 1, access_token: 2
end
Bar.worksheet_id # => 1
Bar.access_token # => 2

实际发生的情况是,forwardable库使用字符串插值来构建转发器方法的定义,即evald.

本质上,它看起来是这样的:

"#{target}.__send__(#{method})"

所以,你可以将任何东西传递为target,它的to_s产生了一些你可以eval然后调用__send__的东西。然而,在你的情况下,Foo.new.to_s有点像#<Foo:0x007fc4aa521ab8>。当插入字符串和evald时,该行以#字符开始,或者简单地说:转发器方法由注释掉的一行组成!这就是它返回nil的原因,因为这就是空方法返回的内容。

最新更新