Ruby 如何检测BasicObject代理?
我正在使用一个BasicObject代理,我需要检测是否传递了一个实际对象或这样的代理。问题是,像is_a?或类没有定义Ruby 如何检测BasicObject代理?,ruby,proxy,ruby-2.3,Ruby,Proxy,Ruby 2.3,我正在使用一个BasicObject代理,我需要检测是否传递了一个实际对象或这样的代理。问题是,像is_a?或类没有定义 module ControllerProxyable extend ActiveSupport::Concern included do attr_reader :controller delegate :current_user, to: :controller end def controller_proxy(controller)
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
因此,以下方法不起作用
Foo.new(controller: nil).bar.some_proxy_method
我如何定义is_a?对于代理或实际标识,我正在使用代理?我实际上找到了RUby 2的答案。我的问题感觉像是重复的,但在我的例子中,我说的是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
问题是,像is_a?或类没有定义
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 ControllerProxy
def class; ControllerProxy end
def is_a?(mod)
self.class < mod
end
end
但是!这违背了代理的全部目的,即与真实事物无法区分。更好的办法是:
class ControllerProxy
def class; Controller end
def is_a?(mod)
Controller < mod
end
end
这不是一个答案,只是一个观察:使用代理的全部意义在于,代理可以作为真实事物的替代品而不加区别地使用。你不应该区分代理和真实的东西。事实上,取决于你问谁,一个对象模拟另一个对象的能力是在中心或OOP,甚至是OOP的定义。@JörgWMittag问题是,在我的服务中,我希望在真实对象上有一个代理,但真实对象可能已经是一个代理了。所以我只是想避免代理超过代理本身,这可能不是一个问题,我不确定这个问题是不是一个骗局。从对象重新绑定方法是一种可能的解决方案,但特别是在代理的情况下,提供自己的实现可能是首选。。。事实上,它可能比我定义的是一个代理更好?这样我就可以保留这张支票了?我喜欢你的第二个建议