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

时间:2015-03-22 16:57:46

标签: ruby

我想将Bar上的类方法委托给Foo类的实例,但是我无法让代理工作。没有任何委托方法抛出错误,getters只返回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.

我做错了什么?

1 个答案:

答案 0 :(得分:3)

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库使用字符串插值来构建转发器方法的定义,然后eval d。

从本质上讲,它看起来像这样:

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

因此,您可以传递target的任何内容,to_s会产生eval的结果,然后调用__send__。但是,在您的情况下,Foo.new.to_s类似#<Foo:0x007fc4aa521ab8>。当插入字符串和eval d时,该行以#字符开头,或者简单地说:转发器方法由一行注释掉!这就是它返回nil的原因,因为这是一个空方法返回的原因。