Search code examples
rubyloopssuperclass

Creating an array of superclasses for a particular class


I'm trying to create an array of all the superclasses for the given class. I tried to solve this problem by using a loop. Why is this not working?

class Object
  def superclasses
    array = []
    klass = self.superclass
    unless klass == nil
      array << klass
      klass = klass.superclass
    end
    array
  end
end

class Bar
end

class Foo < Bar
end

p Foo.superclasses  # should be [Bar, Object, BasicObject]

Solution

  • unless isn't a loop. What you're looking for is until:

    class Object
      def superclasses
        array = []
        klass = self.superclass
        until klass == nil
          array << klass
          klass = klass.superclass
        end
        array
      end
    end
    
    class Bar
    end
    
    class Foo < Bar
    end
    
    p Foo.superclasses # Prints "[Bar, Object, BasicObject]"
    

    Furthermore, you don't need a new method for this. There's already a method called Module#ancestors which does basically what you want:

    class Bar
    end
    
    class Foo < Bar
    end
    
    p Foo.ancestors # Prints "[Foo, Bar, Object, Kernel, BasicObject]"
    

    Note that the return value of ancestors includes Foo itself, and modules which have been included in the inheritance chain, like Kernel. If you don't want that, you can define superclasses like this:

    class Module
      def superclasses
        ancestors[1..-1].select{|mod| mod.is_a? Class }
      end
    end
    
    class Bar
    end
    
    class Foo < Bar
    end
    
    p Foo.superclasses # Prints "[Bar, Object, BasicObject]"