# <!-- rdoc-file=object.c -->
# Classes in Ruby are first-class objects---each is an instance of class Class.
#
# Typically, you create a new class by using:
#
#     class Name
#      # some code describing the class behavior
#     end
#
# When a new class is created, an object of type Class is initialized and
# assigned to a global constant (Name in this case).
#
# When `Name.new` is called to create a new object, the #new method in Class is
# run by default. This can be demonstrated by overriding #new in Class:
#
#     class Class
#       alias old_new new
#       def new(*args)
#         print "Creating a new ", self.name, "\n"
#         old_new(*args)
#       end
#     end
#
#     class Name
#     end
#
#     n = Name.new
#
# *produces:*
#
#     Creating a new Name
#
# Classes, modules, and objects are interrelated. In the diagram that follows,
# the vertical arrows represent inheritance, and the parentheses metaclasses.
# All metaclasses are instances of the class `Class'.
#                              +---------+             +-...
#                              |         |             |
#              BasicObject-----|-->(BasicObject)-------|-...
#                  ^           |         ^             |
#                  |           |         |             |
#               Object---------|----->(Object)---------|-...
#                  ^           |         ^             |
#                  |           |         |             |
#                  +-------+   |         +--------+    |
#                  |       |   |         |        |    |
#                  |    Module-|---------|--->(Module)-|-...
#                  |       ^   |         |        ^    |
#                  |       |   |         |        |    |
#                  |     Class-|---------|---->(Class)-|-...
#                  |       ^   |         |        ^    |
#                  |       +---+         |        +----+
#                  |                     |
#     obj--->OtherClass---------->(OtherClass)-----------...
#
%a{annotate:rdoc:source:from=object.c}
class Class < Module
  # <!--
  #   rdoc-file=object.c
  #   - Class.new(super_class=Object)               -> a_class
  #   - Class.new(super_class=Object) { |mod| ... } -> a_class
  # -->
  # Creates a new anonymous (unnamed) class with the given superclass (or Object
  # if no parameter is given). You can give a class a name by assigning the class
  # object to a constant.
  #
  # If a block is given, it is passed the class object, and the block is evaluated
  # in the context of this class like #class_eval.
  #
  #     fred = Class.new do
  #       def meth1
  #         "hello"
  #       end
  #       def meth2
  #         "bye"
  #       end
  #     end
  #
  #     a = fred.new     #=> #<#<Class:0x100381890>:0x100376b98>
  #     a.meth1          #=> "hello"
  #     a.meth2          #=> "bye"
  #
  # Assign the class to a constant (name starting uppercase) if you want to treat
  # it like a regular class.
  #
  def initialize: (?Class superclass) ?{ (Class newclass) -> void } -> void

  # <!--
  #   rdoc-file=object.c
  #   - class.allocate()   ->   obj
  # -->
  # Allocates space for a new object of *class*'s class and does not call
  # initialize on the new instance. The returned object must be an instance of
  # *class*.
  #
  #     klass = Class.new do
  #       def initialize(*args)
  #         @initialized = true
  #       end
  #
  #       def initialized?
  #         @initialized || false
  #       end
  #     end
  #
  #     klass.allocate.initialized? #=> false
  #
  def allocate: () -> untyped

  # <!--
  #   rdoc-file=object.c
  #   - attached_object -> object
  # -->
  # Returns the object for which the receiver is the singleton class.
  #
  # Raises an TypeError if the class is not a singleton class.
  #
  #     class Foo; end
  #
  #     Foo.singleton_class.attached_object        #=> Foo
  #     Foo.attached_object                        #=> TypeError: `Foo' is not a singleton class
  #     Foo.new.singleton_class.attached_object    #=> #<Foo:0x000000010491a370>
  #     TrueClass.attached_object                  #=> TypeError: `TrueClass' is not a singleton class
  #     NilClass.attached_object                   #=> TypeError: `NilClass' is not a singleton class
  #
  def attached_object: () -> untyped

  # <!--
  #   rdoc-file=object.c
  #   - inherited(subclass)
  # -->
  # Callback invoked whenever a subclass of the current class is created.
  #
  # Example:
  #
  #     class Foo
  #       def self.inherited(subclass)
  #         puts "New subclass: #{subclass}"
  #       end
  #     end
  #
  #     class Bar < Foo
  #     end
  #
  #     class Baz < Bar
  #     end
  #
  # *produces:*
  #
  #     New subclass: Bar
  #     New subclass: Baz
  #
  def inherited: (Class arg0) -> untyped

  # <!--
  #   rdoc-file=object.c
  #   - class.new(args, ...)    ->  obj
  # -->
  # Calls #allocate to create a new object of *class*'s class, then invokes that
  # object's #initialize method, passing it *args*.  This is the method that ends
  # up getting called whenever an object is constructed using `.new`.
  #
  def new: () -> untyped

  # <!--
  #   rdoc-file=object.c
  #   - subclasses -> array
  # -->
  # Returns an array of classes where the receiver is the direct superclass of the
  # class, excluding singleton classes. The order of the returned array is not
  # defined.
  #
  #     class A; end
  #     class B < A; end
  #     class C < B; end
  #     class D < A; end
  #
  #     A.subclasses        #=> [D, B]
  #     B.subclasses        #=> [C]
  #     C.subclasses        #=> []
  #
  # Anonymous subclasses (not associated with a constant) are returned, too:
  #
  #     c = Class.new(A)
  #     A.subclasses        # => [#<Class:0x00007f003c77bd78>, D, B]
  #
  # Note that the parent does not hold references to subclasses and doesn't
  # prevent them from being garbage collected. This means that the subclass might
  # disappear when all references to it are dropped:
  #
  #     # drop the reference to subclass, it can be garbage-collected now
  #     c = nil
  #
  #     A.subclasses
  #     # It can be
  #     #  => [#<Class:0x00007f003c77bd78>, D, B]
  #     # ...or just
  #     #  => [D, B]
  #     # ...depending on whether garbage collector was run
  #
  def subclasses: () -> Array[Class]

  # <!--
  #   rdoc-file=object.c
  #   - class.superclass -> a_super_class or nil
  # -->
  # Returns the superclass of *class*, or `nil`.
  #
  #     File.superclass          #=> IO
  #     IO.superclass            #=> Object
  #     Object.superclass        #=> BasicObject
  #     class Foo; end
  #     class Bar < Foo; end
  #     Bar.superclass           #=> Foo
  #
  # Returns nil when the given class does not have a parent class:
  #
  #     BasicObject.superclass   #=> nil
  #
  def superclass: () -> Class?
end
