rubyproxyruby-2.3

How to detect a BasicObject Proxy?


I am using a BasicObject Proxy and I need to detect whether I have passed an actual object OR such a proxy. Problem is that methods such as is_a? or class are not defined

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

This is an example of how I am using it :

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

The following therefore doesn't work

Foo.new(controller: nil).bar.some_proxy_method

How can I define is_a? for a Proxy (or actually identifying I am using a proxy) ?


Solution

  • Problem is that methods such as is_a? or class are not defined

    The obvious solution to the problem "some method is not defined", is to define the method:

    class ControllerProxy
      def class; ControllerProxy end
    
      def is_a?(mod)
        self.class < mod
      end
    end
    

    But! This defeats the whole purpose of a proxy, which is to be indistinguishable from the real thing. A better way would be IMO:

    class ControllerProxy
      def class; Controller end
    
      def is_a?(mod)
        Controller < mod
      end
    end