Here is an example:
class A
class << self
p superclass
end
end
a = A.new
class << a
p superclass
end
This code print:
#<Class:Object>
A
Why instead of
Class
A
print line
#<Class:Object>
A
?
For an anonymous class
class << self
p superclass
end
superclass is Class
I am not 100% sure if I understand the question correctly. Please rephrase it or provide more details in case I misunderstood it.
A call to superclass returns an object, which in this case is Class. In Ruby everything is an object. To my knowledge this is correct behaviour.
If you want to see the name of the class only, call p superclass.name.
Edit A call to superclass can return nil. When you do: class << a, you are extending a with new methods (take a look at this reading about classes, objects and modules). Since a is an Object (an instance of class A), it has no superclass - Object is the top of hierarchy tree. Class A has a superclass (class named Class), but not the instance of A it.
Related
By definition, a singleton class of an object also inherits the singleton class of the superclass of the object. The BasicObject in ruby doesn't have any superclass as it is the most basic level class
>> BasicObject.superclass
=> nil
But when the same method called on its singleton class, it results:
>> BasicObject.singleton_class.superclass
=> Class
and also why no other object in ruby have the Class class as its superclass?
How the logic behind the superclass of singleton_class of BasicObject is implemented in Ruby?
In general, the superclass of the singleton class of an object is the class of the object. I.e. for any object foo with a singleton class, the following holds:
foo.singleton_class.superclass == foo.class
However, for classes, this would be somewhat boring: the class of every class is Class, so the superclass of every class's singleton class would always be Class.
That is not particularly useful, since it would break some reasonable assumptions. For example, if I have something like this:
class Super
def self.super_singleton_method; end
end
class Sub < Super; end
I would expect to be able to call Sub.super_singleton_method. However, in order to do this, Super.singleton_class needs to be somewhere in the method lookup chain of Sub.singleton_class.
So, for classes, the rule is somewhat different: the superclass of the singleton class of a class is the singleton class of the superclass of the class. I.e. for any class Foo, the following holds:
Foo.singleton_class.superclass == Foo.superclass.singleton_class
If you want, you can check whether this is true for every class in your system:
ObjectSpace.each_object(Class).select do |klass|
klass.singleton_class.superclass != klass.superclass.singleton_class
end
#=> [BasicObject]
So, as you can see, this property does hold for all classes except BasicObject.
The simple answer for why BasicObject is different is that BasicObject has no superclass, and thus we cannot apply the rule. So, we fall back on the more general rule for all objects that
foo.singleton_class.superclass == foo.class
And BasicObject's class is Class, therefore,
BasicObject.singleton_class.superclass == BasicObject.class
BasicObject.singleton_class.superclass == Class
and also why no other object in ruby have the Class class as its superclass?
The only reason to inherit from Class would be to override the behavior of how inheritance or method lookup works in Ruby. But Ruby does not allow to override this. How inheritance and method lookup works is part of the language specification and cannot be changed. Therefore, inheriting from Class is illegal:
class MyClass < Class; end
# can't make subclass of Class (TypeError)
Thus there cannot be any object which has Class as its superclass, except singleton classes of classes. (Ruby can of course break its own rules since it is the one that makes the rules.)
How the logic behind the superclass of singleton_class of BasicObject is implemented in Ruby?
It isn't. You cannot explain how this works in Ruby, since it is part of the definition of Ruby itself.
It is similar to how Class is a subclass of Module, but Module is a class, i.e. an instance of Class. You cannot explain this from within Ruby using the rules of Ruby, but the Ruby implementation can, of course, set things up so that this works, since the Ruby implementation itself does not have to abide by the rules of Ruby: it is the one enforcing the rules, so it can just choose not to enforce them for itself.
By definition, a singleton class of an object also inherits the singleton class of the superclass of the object.
Instead of taking this for granted, let's figure out why it was implemented this way.
In Ruby, there are instance methods and class methods. The class methods however are in fact instance methods of the singleton class:
class MyClass
def foo
end
def self.bar
end
end
MyClass.instance_methods(false)
#=> [:foo]
MyClass.singleton_class.instance_methods(false)
#=> [:bar]
As a diagram:
MyClass ---> #<Class:MyClass>
foo bar
Now, if you create a subclass MySubClass, it inherits both, the instance methods and the class methods from its superclass MyClass:
class MySubClass < MyClass
end
MySubClass.instance_methods
#=> [:foo, ...]
MySubClass.singleton_class.instance_methods
#=> [:bar, ...]
To get this working, the inheritance has to be established for both, the classes and the singleton classes:
MyClass ---> #<Class:MyClass>
foo bar
^ ^
| |
MySubClass ---> #<Class:MySubClass>
Ruby optimized this internally – the singleton classes are only created when needed. But conceptually, this is what happens.
Apart from that, MyClass and MySubClass already come with some built-in class methods, most notably .new which is used to create instances, but also .superclass.
You might know that the default implementation of .new calls .allocate under the hood. So somewhere there must be a sort of "root class" which contains these methods. And since they are class methods, it must sit on top of the singleton class side:
<singleton root class>
new
allocate
superclass
^
|
...
|
MyClass ---> #<Class:MyClass>
foo bar
^ ^
| |
MySubClass ---> #<Class:MySubClass>
And this mysterious top level singleton root class that provides the fundamental class methods for all other classes is ... Class!
Class.instance_methods(false)
#=> [:allocate, :superclass, :subclasses, :new]
Regarding:
class Test
class << self
def hi
puts "Hi there"
end
end
I came up with following image in my head:
Since everything is an object in Ruby, classes themselves are objects of class Class. By calling class << self you open up Class definition from the inside of Test and inject few instance methods. Since Test is an instance of Class, you can call those methods same way you call instance methods on your objects: Test.hi.
Following is the pseudo code which helps to visualise my previous sentence:
class Class
def hi
puts “Hi there”
end
end
Test = Class.new(class Test
end)
Test.hi
Am I getting this right?
Suppose we have an object obj of class A. At this point, the ancestor hierarchy of obj's class is:
[A, ...]
What class << obj; ... end does is that it creates a class B whose only instance is obj, and puts it in the ancestor hierarchy of obj so that the ancestor hierarchy of the obj's class becomes:
[B, A, ...]
If you write class << self; ... end within the context of Test, then the body of it will be a class whose sole instance is Test. If you define an instance method hi within that body, then that will apply to instances of that class, which is Test. Hence you will be able to do Test.hi.
How can I get the class name of an instance of BasicObject in Ruby? For example, say I have this:
class MyObjectSystem < BasicObject
end
puts MyObjectSystem.new.class
How can I make this code succeed?
EDIT: I've found that Object's instance method class is defined as return rb_class_real(CLASS_OF(obj));. Any way to use this from Ruby?
I spent some time playing around with irb and came up with this:
class BasicObject
def class
klass = class << self; self; end # get the object's singleton class
klass.superclass # the superclass of an object's singleton class is that object's class
end
end
That will give any object that inherits from BasicObject a #class method that you can call.
Edit
Further explanation as requested in the comments:
Say you have object obj that is an instance of class Foo. obj gets its instance methods from those that are defined within the class Foo, in addition to the methods defined in Foo's parent class and so on up the inheritance chain. Ruby lets you define methods directly on an object that are only accessible to that particular object like this
obj = Foo.new
def obj.hello
puts "hello"
end
obj.hello #=> hello
other_obj = Foo.new
other_obj.hello #=> Method missing error
The reason you can do this is because every object has something called a singleton class (or sometimes call an eigenclass) that you are actually defining the method on. This singleton class actually exists in the inheritance chain of the object directly beneath the object's actual class. That makes the object's actual class, Foo in this example, the superclass of the object's singleton class.
The class << self line you see in the answer is a special syntax for entering the scope of an object's singleton class. So in the example above, you could also define a method in an object's singleton class like this
class << obj
def goodbye
puts "goodbye"
end
end
obj.goodbye #=> goodbye
So the line class << self; self; end is opening the object's singleton class (whatever object is currently self) and then returning self (self has now become the singleton class), which can then be assigned to a variable to do what you wish with.
I would recommend reading Metaprogramming Ruby if you want a better explanation of all this. It definitely gives you a much better understanding of the Ruby object model as a whole.
I have to leave in a few minutes so I can't test it myself, but it seems like you could make a separate module that uses ffi to call rb_class_real from libruby. If I had more time I would test it first, but nobody else has answered yet and I don't want you leave you totally out in the cold.
Based on Jeff Smith's answer, you can do this without modifying BasicObject:
class << object; self; end.superclass
where object is an instance of an object whose class you want, i.e.,
irb(main):001:0> object = BasicObject.new
(Object doesn't support #inspect)
=>
irb(main):002:0> class << object; self; end.superclass
=> BasicObject
the ruby book I'm reading has confused me a bit. If I do the following, I understand completely why the code throws an error;
class Person
def show_name
puts #name
end
end
person = Person.new
person.show_name
Person.show_name #(note the capital P) this line falls over
It throws an error stating that the Person class does not have a method called show_name, because it is an instance method. I understand this completely. The book then throws in this example;
class Class
def add_accessor(accessor_name)
self.class_eval %Q{attr_accessor :#{accessor_name}}
end
end
class Person
end
person = Person.new
Person.add_accessor :name #note the capital P
Person.add_accessor :age #capital P here too
person.name = "Mikey"
person.age = 30
puts person.name
and goes on to state how cool it is that you can add methods to classes dynamically. What I don't understand is why I am suddenly allowed to call the "add_accessor" method as a class method (with a capital P) when the method itself isn't defined as such? I thought all class methods had to be declared like this?
class Math
def self.PI
3.141
end
end
puts Math.PI
Is anyone able to enlighten me?
Ruby classes are objects like everything else to. Your Person class is really an object of class Class, which in turn inherits from class Module. When you add a method to class Class as an instance method, you are providing a new method for all classes.
If you had declared it with a def in Person, it would not be callable without an object. To add class methods for one class, but not all, you must prepend the method name with self or the name of the class:
class Person
def instance_method
end
def self.class_method
end
def Person.other_class_method
end
end
When you declare the method as self.class_method you are declaring your method to be a singleton method on the class object. self in a class or module declaration refers to the class object, which is why self. and Person. are the same.
When dealing with Ruby, just remember everything is an object, everything has methods. There are no functions in Ruby either, despite appearances to the contrary. Methods and objects, always.
Look at this:
person.instance_of?(Person) #=> true
Person.instance_of?(Class) #=> true
You have defined an instance method add_accessor for all the instances of the class Class, so Person class can use that method because it is an instance of Class.
I recommend yout to take a look at metaprogramming and Ruby Object Model.
Hoep this helps
You're extending the Class class, and all of your classes, like Person, are instances of Class (Yes, classes are instances of the Class class. They're ordinary objects).
So when you call Person.add_accessor, you're calling the instance method Class#add_accessor.
because Person (with capital P ) is an instance of the class Class.
In Ruby, we could use super within singleton method to call the corresponding super class's singleton method, like the following code shows.
class Base
def self.class_method
puts "Base class method"
end
end
class Derived < Base
def self.class_method
puts "Derived class method"
super
end
end
Derived.class_method
# Derived class method
# Base class method
However, I don't seem quite get how that call to super within Derived.class_method could reach Base.class_method. I'd assume that class_method is defined on their metaclass, does that mean their metaclass has parent/child relationship? (I can't quite confirm that by experiments)
Update: I'm asking this question because I remembered seeing somewhere there's some kind of relationship bettwen base and derived class' metaclass (but I can't find it any more). In addition to know how actually super works, I'd also like to confirm whether the two metaclasses are totally separate or not.
There are four class objects in play here:
<Class>---class---><Class>
Base #Base
^ ^
| |
| |
super super
| |
| |
<Class> <Class>
Derived---class--->#Derived
Nomenclature:
<...> is the class of each object.
The name of the class is on the second line.
If the name starts with #, it's the eigenclass (aka singleton class).
super points to a class's superclass
class points to the class's class.
When you call Derived.class_method, Ruby follows the "right one and then up" rule: First go to the object's class, then follow the superclass chain up, stopping when the method is found:
The receiver of the "class_method" call is Derived. So follow the chain right to Derived's class object, which is its eigenclass (#Derived).
Derived does not define the method, so Ruby follows the chain up the chain to #Derived's superclass, which is #Base.
The method is found there, so Ruby dispatches the message to #Base.class_method
You don't think I knew all this stuff off the top of my head, did you? Here's where my brain got all this meta juju: Metaprogramming Ruby.
Part 2. How to make an "eigenclass" (aka "singleton class") come out of hiding
class Object
def eigenclass
class << self
self
end
end
end
This method will return the eigenclass of any object. Now, what about classes? Those are objects, too.
p Derived.eigenclass # => #<Class:Derived>
p Derived.eigenclass.superclass # => #<Class:Base>
p Base.eigenclass # => #<Class:Base>
Note: Above is from Ruby1.9. When run under Ruby 1.8, you get a surprise:
p Derived.eigenclass.superclass # => #<Class:Class>
To clarify and correct what i wrote in the comments regarding the way Ruby hides/exposes eigenclasses, here is the situation:
Ruby 1.8:
(1) The Object#class method always returns the first real (non eigenclass or iclass) superclass of the actual class of an object.
e.g
o = Object.new
class << o; end
o.class #=> returns Object, even though the _actual_ class is the eigenclass of o
In other words, the Object#class method will never return an eigenclass, it passes over them
and instead returns the first 'real' class it finds in the inheritance hierarchy.
(2) The Class#superclass method has two cases. If the receiver is not an eigenclass then it simply returns the superclass. However, if the receiver is an eigenclass then this method returns the actual (i.e not necessarily real) class of the receiver.
# case where receiver is a normal class (i.e not an eigenclass)
Module.superclass #=> Object (behaves as expected)
# case where receiver is an eigenclass
class << Module; superclass; end #=> returns Class, this is NOT the superclass
From above, Class#superclass behaves as expected in the case of a normal class, but for the eigenclass example it states the superclass of the eigenclass of Module is Class which is not true. From this diagram http://banisterfiend.wordpress.com/2008/10/25/the-secret-life-of-singletons/ we know that the superclass of the eigenclass of Module is actually the eigenclass of Object. I am unsure why Ruby 1.8 has this strange behaviour.
Ruby 1.9:
(1) The Object#class method behaves identically to the 1.8 version.
(2) The Class#superclass method no longer has two cases, it now treats eigenclasses the same way it treats normal classes and returns the actual superclass as expected.
e.g
class << Module; superclass; end #=> #<Class:Object>
This diagram explains the relationship: http://banisterfiend.wordpress.com/2008/11/25/a-complete-ruby-class-diagram/
Also, here are some other posts that explain more the intricacies of eigenclasses:
http://www.klankboomklang.com/2007/10/05/the-metaclass/
http://www.klankboomklang.com/2007/09/21/the-singleton-class/
And here's a fairly hard-going one that explains more than you'd probably like to know:
http://banisterfiend.wordpress.com/2008/10/25/the-secret-life-of-singletons/