On Sat, Jan 21, 2012 at 9:03 PM, John M. [email protected] wrote:
1.9.2p290 :007 > Class.instance_of? Object
=> false
You might look at the difference between “instance_of?”
and “kind_of?” to understand this.
peterv@ASUS:~$ irb
001:0> Class
=> Class
the Class constant is defined
002:0> Class.class
=> Class
it’s class is Class
003:0> Class.instance_of? Object
=> false
it is not an instance of the class Object
004:0> Class.kind_of? Object
=> true
but … the class of Class (Class that is), is derived from Object
005:0> Class.ancestors
=> [Class, Module, Object, Kernel, BasicObject]
and here you can see ancestor chain (proving that Class, as the class
of
Class, is derived from Object).
Since newer rubies (1.9.3 I believe ??) There is even a BasicObject on
top of the chain
(Object would not longer be at the top/root of the chain).
006:0> Class.object_id
=> 74033900
this object_id is an example of a method that is available on Class,
but
really inherited from Object.
007:0> class C
008:1> end
=> nil
009:0> C.respond_to?(:new)
=> true
Now when we create an instance ‘C’ of class Class (that is we define a
class C)
that instance has the method “new” (that is why we can call ‘new’ on a
class)
010:0> module M
011:1> end
=> nil
012:0> M.respond_to?(:new)
=> false
But when we create an instance ‘M’ of class Module (that is we define
a
module M) that does not have the method “new” available.
This is another proof that Class is not at the top/root of the
hierarchy. If
that was the case, then all objects (also a Module instance M) would
have to inherit the ‘new’ method from Class. But really all objects
(except instances of BasicObject have the object_id method).
016:0> bo = BasicObject.new
(Object doesn’t support #inspect)
=>
017:0> bo.object_id
NoMethodError: undefined method object_id' for #<BasicObject:0x8f90224> from (irb):17 from /home/peterv/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in
’
1.9.2p290 :008 > defined? Class
=> “constant”
1.9.2p290 :009 > Class.class
=> Class
1.9.2p290 :010 > Object.class
=> Class
Class is an instance of Class. That is, Class is an instance of
itself. And therefore “Class” just is (kind of like the idea if
something stems from something else, how was the very first thing
created - it just was).
It is not because the class of Class is Class, that Class cannot have
a different superclass. Maybe you are confusing the relationship
“is an instance of” with the relationship “superclass”.
And yes, all classes (and also Class itself) point to Class for
“is an instance of”.
But in the superclass hierarchy, Class is certainly not at the top.
I actually think it is a leaf, since an experiment to make a subclass
of “Class” failed …
021:0> class Test < Class
022:1> puts “a derived class of Class”
023:1> end
TypeError: can’t make subclass of Class
from (irb):21
from /home/peterv/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in `’
Class is just an internal construct, built
part of the language for templating.
So Object is a constant that represents an object allocated in memory.
When it’s methods are searched for it looks up the scope chain, first
at the singleton class (just in case any methods are extended on
Object) and after that, it looks at its immediate parent which is
Class,
I think that is incorrect:
027:0> Object.superclass
=> BasicObject # the superclass of Object is BasicObject
and hence that’s why we can say Object.new, since Class class
defines “new”.
The reason we can say Object.new is because the class of Object is
Class and that class Class has defined “new”.
048:0> Object.class
=> Class
049:0> Object.methods.grep(/new/)
=> [:new]
For a module, e.g. that does not work:
053:0> module M
054:1> end
=> nil
055:0> M.methods.grep(/new/)
=> []
Now this is the interesting part. There obviously is a difference
between Object and Class. As already stated, Object is an instance of
Class and therefore inherits from Class, not visa versa.
Check the difference between the “class” (is an instance of) and the
“superclass” relationship.
B = Object.new
This fails:
1.9.2p290 :007 > B.new
NoMethodError: undefined method `new’ for #Object:0x007ff597d27820
That just works here …
058:0> B = Object.new
=> #Object:0x9013cdc
059:0> B.class
=> Object
060:0> B.superclass
NoMethodError: undefined method superclass' for #<Object:0x9013cdc> from (irb):60 from /home/peterv/.rvm/rubies/ruby-1.9.3-p0/bin/irb:16:in
’
When we instantiate B, the instance gets B’s instance methods. But why
doesn’t it get Class’s instance method (new)?
I don’t understand this …
B inherits from Object
B is an instance of Object, it does not “inherit” from it.
On B, there is no “superclass” method (only classes have a
superclass method).
HTH,
Peter
–
Peter V.
http://twitter.com/peter_v
http://rails.vandenabeele.com