Search code examples
rubyintrospectiondelegation

Ruby: is_a? and instance_of? in BasicObject


How do is_a? and instance_of? methods work with a subclass of BasicObject ?

class My < BasicObject
  DELEGATE = [:is_a?, :instance_of?]
  def method_missing(name, *args, &blk)
    superclass unless DELEGATE.include? name
    ::Kernel.send(name,*args, &blk) 
  end
end

my = My.new
my.is_a? BasicObject  #=> true
my.is_a? My           #=> false ???
my.instance_of? My    #=> false ???

Solution

  • You can steal is_a? from Kernel:

    class My < BasicObject
      define_method(:is_a?, ::Kernel.method(:is_a?))
    end
    
    m = My.new
    m.is_a?(My)          #=> true
    m.is_a?(BasicObject) #=> true
    m.is_a?(Object)      #=> false
    

    If you're going to build your own object hierarchy, you could also define your own Kernel, something like:

    module MyKernel
      [:is_a?, :instance_of?, :class].each do |m|
        define_method(m, ::Kernel.method(m))
      end
    end
    
    class My < BasicObject
      include ::MyKernel
    end