Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何检测BasicObject代理?_Ruby_Proxy_Ruby 2.3 - Fatal编程技术网

Ruby 如何检测BasicObject代理?

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)

我正在使用一个BasicObject代理,我需要检测是否传递了一个实际对象或这样的代理。问题是,像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
因此,以下方法不起作用

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问题是,在我的服务中,我希望在真实对象上有一个代理,但真实对象可能已经是一个代理了。所以我只是想避免代理超过代理本身,这可能不是一个问题,我不确定这个问题是不是一个骗局。从对象重新绑定方法是一种可能的解决方案,但特别是在代理的情况下,提供自己的实现可能是首选。。。事实上,它可能比我定义的是一个代理更好?这样我就可以保留这张支票了?我喜欢你的第二个建议