我想将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
方法家族的第一个参数是Symbol
或String
(或实现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
的原因,因为这就是空方法返回的内容。