Yes, Object, Class, and Module are more than just constants. Object,
Class, and Module are instances of Class class:
1.9.3p0 :031 > Class.class
=> Class
1.9.3p0 :032 > Module.class
=> Class
1.9.3p0 :033 > Object.class
=> Class
Since Object, Class, and Module are instances of Class class, they
don’t have access to Class’s singleton methods, but rather they have
access to Class’s instance methods:
1.9.3p0 :052 > class Class
1.9.3p0 :053?> def Class.abc
1.9.3p0 :054?> puts ‘abc’
1.9.3p0 :055?> end
1.9.3p0 :056?> end
=> nil
1.9.3p0 :076 > Module.abc
NoMethodError: undefined method `abc’ for Module:Class
1.9.3p0 :077 > Object.abc
NoMethodError: undefined method `abc’ for Object:Class
However, since we defined the singleton method on Class, it will work
on a Class invocation:
1.9.3p0 :078 > Class.abc
abc
=> nil
But instance methods work:
1.9.3p0 :012 > Class.instance_methods(false)
=>
[:allocate, :new, :superclass, :cattr_reader, :cattr_writer,
:cattr_accessor,
]
1.9.3p0 :015 > Object.cattr_writer
=> []
1.9.3p0 :017 > Module.cattr_reader
=> []
1.9.3p0 :018 > Class.cattr_writer
=> []
This here is an indication that Object and Module are instances of
Class but DO NOT inherit from Class. Let’s check that out with the
superclass call:
1.9.3p0 :079 > Class.superclass
=> Module
1.9.3p0 :080 > Module.superclass
=> Object
1.9.3p0 :081 > Object.superclass
=> BasicObject
1.9.3p0 :082 > BasicObect.superclass
=> nil
Thus, Class inherits from Module, and Module in turn inherits from
Object, which in turn inherits from BasicObject in ruby 1.9. We can
test that out by seeing if we define a singleton method on Module,
then Class should be able to invoke it, since there is inheritance
between them.
1.9.3p0 :067 > class Module
1.9.3p0 :068?> def Module.qqqw
1.9.3p0 :069?> puts ‘qqqw’
1.9.3p0 :070?> end
1.9.3p0 :071?> end
=> nil
1.9.3p0 :072 > Module.singleton_methods(false)
=>
[:nesting, :constants, :attr_internal_naming_format,
:attr_internal_naming_format=, :qqqw]
1.9.3p0 :073 > Class.qqqw
qqqw
=> nil
1.9.3p0 :074 > Object.qqqw
NoMethodError: undefined method `qqqw’ for Object:Class
1.9.3p0 :084 > class Object
1.9.3p0 :085?> def Object.ttyy
1.9.3p0 :086?> puts ‘ttyy’
1.9.3p0 :087?> end
1.9.3p0 :088?> end
=> nil
1.9.3p0 :089 > Module.ttyy
ttyy
=> nil
1.9.3p0 :090 > Class.ttyy
ttyy
=> nil
This shows the role of inheritance. We defined a singleton method on
Object, and thus since Module inherits from Object, it had access to
it, and so did Class, since Class inherits from Module, which in turn
inherits from Object.
Now that’s the metaclass (eigenclass) inheritance relationship (the
fact that the eighenclass of Class inherits the singleton methods of
the eighenclass of Module which in turn inherits the singleton methods
of eigenclass of Object). If the inheritance relationship did not
exist as it does, then we wouldnt be able to call singleton methods of
Module on Class, for example.
Furthermore, we have a circular relationship. Since Class is an
instance of Class, Module is an instance of Class, and Object is an
instance of Class, they all have access to instance methods of Class,
as already stated. What’s more interesting is the circular
relationship that has been created via the combination of
instantiation and inheritance. If Object is an instance of Class, and
Class inherits from Module, then that means Class is an instance of
Module, and so since Object is an instance of Class, it itself is an
instance of Module. Hence, we can access the INSTANCE METHODS of any
of these classes via the other Class.
1.9.3p0 :094 > Class.is_a?(Module)
=> true
1.9.3p0 :095 > Module.is_a?(Class)
=> true
1.9.3p0 :096 > Object.is_a?(Module)
=> true
1.9.3p0 :097 > Object.is_a?(Class)
=> true
Now lets access an instance method of Module on Object:
1.9.3p0 :098 > Module.instance_methods(false)
=>
[:freeze, :===, :==, :<=>, :<, :<=, :>, :>=, :to_s, :included_modules,
:include?, :name, :ancestors, :instance_methods,
:public_instance_methods, :protected_instance_methods,
:private_instance_methods, :constants, :const_get, :const_set,
:const_defined?, :class_variables, :remove_class_variable,
:class_variable_get, :class_variable_set, :class_variable_defined?,
:public_constant, :private_constant, :module_exec, :class_exec,
:module_eval, :class_eval, :method_defined?, :public_method_defined?,
:private_method_defined?, :protected_method_defined?,
:public_class_method, :private_class_method, :autoload, :autoload?,
:instance_method, :public_instance_method, :psych_yaml_as, :yaml_as,
:deprecate, :alias_method_chain, :alias_attribute, :mattr_reader,
:mattr_writer, :mattr_accessor, :remove_possible_method,
:redefine_method, :delegate, :instance_method_names, :method_names,
:attr_internal_reader, :attr_internal_writer, :attr_internal_accessor,
:attr_internal, :anonymous?, :duplicable?, :reachable?, :parent_name,
:parent, :parents, :local_constants, :local_constant_names,
:attr_accessor_with_default, :synchronize, :pretty_print_cycle,
:pretty_print, :xyz]
1.9.3p0 :099 > Object.included_modules
=> [PP::ObjectMixin, ActiveSupport::Dependencies::Loadable,
JSON::Ext::Generator::GeneratorMethods::Object, Kernel]
And there you go, it worked.