我正在使用BasicObject代理,我需要检测是否已经传递了实际对象或这样的代理。问题是未定义is_a?
或class
等方法
module ControllerProxyable
extend ActiveSupport::Concern
included do
attr_reader :controller
delegate :current_user, to: :controller
end
def controller_proxy(controller)
# is_a? actually is NOT defined for a BasicObject causes the following to crash
@controller = if controller.is_a?(ControllerProxy)
controller
else
ControllerProxy.new(controller)
end
end
end
class ControllerProxy < BasicObject
def initialize(controller = nil)
@controller = controller
end
def some_proxy_method
end
# def respond_to and respond_to_missing not relevant here
end
这是我如何使用它的一个例子:
class Foo
include ControllerProxyable
def initialize(controller: nil)
controller_proxy(controller)
end
def bar
bar ||= Bar.new(controller: controller)
end
end
class Bar
include ControllerProxyable
def initialize(controller: nil)
controller_proxy(controller)
end
end
以下因此无效
Foo.new(controller: nil).bar.some_proxy_method
如何为代理定义is_a?
(或实际识别我正在使用代理)?
答案 0 :(得分:1)
问题是
is_a?
或class
等方法未定义
问题的明显解决方案&#34;某些方法未定义&#34;,是定义方法:
class ControllerProxy
def class; ControllerProxy end
def is_a?(mod)
self.class < mod
end
end
但是!这违背了代理的整个目的,这与真实的东西无法区分。一个更好的方法是IMO:
class ControllerProxy
def class; Controller end
def is_a?(mod)
Controller < mod
end
end
答案 1 :(得分:0)
我实际上找到了RUby 2 here的答案。我的问题几乎感觉像是重复但在我的情况下,我在谈论basicObject类的扩展而不是修补BasicObject类本身
对于这样的用例,这变为:
def controller_proxy(controller)
# Note that is_a? is not defined for a proxy
@controller = if Kernel.instance_method(:class).bind(controller).call <= ServiceControllerProxy
controller
else
ServiceControllerProxy.new(controller)
end
end