I have two questions:
Does method f_1 belong to the metaclass anonymous class?
Does method f_2 belong to the anonymous class?
related to the following code:
car = "car"
class << car
def self.f_1
puts "f_1"
end
def f_2
puts "f_2"
end
end
Since ruby's own API uses the term "singleton class," I'd say the following are true:
f_1 is a class method on car's singleton class and can be called like this:
car.singleton_class.f_1
f_2 is an instance method on car's singleton class and can be called like this:
car.f_2
Well, terminology is frangible, but FWIW I would say your class wasn't really an anonymous class. As for belonging, both of these methods only exist in the car object.
I'll be honest and admit that I'm a little vague about the difference between a class method and an instance method when the class is defined against an individual object like this -- I would guess that if there is any difference, it will be an obscure one that will make your code much harder to read ;)
Update: You might find this helpful, if you've not seen it before. (Personally, it makes my head hurt, but everyone's different...)
I was under the impression that an anonymous class is a class that has no name:
my_class = Class.new
my_class.name # => nil
However, the Pickaxe refers to it as a unnamed class rather than as an anonymous class.
A reformulation of Rob Davis' answer:
The method-owner of :f_1 is car.singleton_class.singleton_class.
The method-owner of :f_2 is car.singleton_class.
The chain car → car.singleton_class → car.singleton_class.singleton_class corresponds to the bottom row in the diagram at http://www.atalon.cz/rb-om/ruby-object-model/#sc-inheritance-sample.
Notes:
The code does NOT create any new class (in particular, no anonymous class is created).
In most Ruby programs, eigenclasses of eigenclasses are NOT made "actual" (see http://www.atalon.cz/rb-om/ruby-object-model/#actual-lists).
Related
From Wikibooks' Ruby Programming/Overview:
When I said that every Ruby object has a class, I lied. The truth is, every object has two classes: a “regular” class and a singleton class. An object’s singleton class is a nameless class whose only instance is that object. Every object has its very own singleton class, created automatically along with the object. Singleton classes inherit from their object’s regular class and are initially empty, but you can open them up and add methods to them, which can then be called on the lone object belonging to them. This is Ruby’s secret trick to avoid “class methods” and keep its type system simple and elegant
The above passage says that Ruby's secret trick to avoid class methods. I don't understand what the author means here. Where is Ruby stopping us to avoid class methods? for an example, look at the example shown below
class Raj
def self.hi
puts 'Hi'
end
def hello
puts 'hello'
end
end
object=Raj.new
object.hello
Raj.hi
As you can see in the preceding example, the class methods can still be created.
yes?
I understand that there are no true class methods in Ruby; instead, they are methods that are created for the Raj object.
But, in any case, it's allowing me to create the method 'hi,' right?
So, what does it mean when it says, 'This is Ruby's secret trick for avoiding "class methods" and keeping its type system simple and elegant'?
I understand that there are no true class methods in Ruby; instead, they are methods that are created for the Raj object.
That's exactly it, though.
def self.hi
puts 'Hi'
end
This is not a class method or static method. Those don't exist in Ruby. That's the whole point. Your class Raj defines an object of type Class. We can see its type with the #class function.
> Raj.class
=> Class
We can also see its ancestors.
> Raj.class.ancestors
=> [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject]
Class inherits from Module, since (for the most part) classes can do everything modules can. Module, in turn, inherits from Object, which has some modules of its own mixed in (PP:ObjectMixin is for pretty-printing, and Kernel gets you the nice helpers like puts) and eventually inherits from the root class BasicObject.
But this isn't the whole story, for Raj has its own class as well: its singleton class. We can see the full story by calling #singleton_class instead of #class.
> Raj.singleton_class.ancestors
=>
[#<Class:Raj>,
#<Class:Object>,
#<Class:BasicObject>,
Class,
Module,
Object,
PP::ObjectMixin,
Kernel,
BasicObject]
Now there's a lot more going on. Raj is an instance of the singleton class of Raj, which inherits from the singleton class of Object, which in turn inherits from the singleton class of BasicObject, which inherits from Class and all of the stuff we saw before.
So when you define a method on the class Raj, you're defining it (as an instance method) on the singleton class #<Class:Raj>. And that class (currently) has one instance: Raj.
By the way, it's also useful to know that the term "singleton class" is a bit of a lie. As you can see, the class is very much not a singleton in general. For instance, the singleton class of Object, called #<Class:Object> above, actually has several instances: Object, Raj, String, and most Ruby classes. Personally, I prefer to call them eigenclasses for that reason, but "singleton class" is the official (and more well-known) term.
The author is talking about the singleton class in this sentence, there is a really nice article to deep dive into ruby singleton class: https://medium.com/#leo_hetsch/demystifying-singleton-classes-in-ruby-caf3fa4c9d91
Here is a nice example extracted from this article:
class Vehicle
def initialize(kms)
#kms = kms
end
def drive
puts "let's go!"
end
end
car = Vehicle.new(1000)
bus = Vehicle.new(3000)
def car.drive
print "I'm driving a car! "
super
end
car.drive # "I'm driving a car! let's go!"
bus.drive # "let's go!"
As you can see, here the #drive method has been overridden but only for the car object, the bus object is still using the #drive method defined in the Vehicle class.
This new method is defined on the singleton class (or shadow class) of the object, this is allowing you to define new methods on the fly on an object without polluting all the objects of this class.
This means that Ruby doesn't implement class methods.
Indeed, the Ruby OBJECT Model, allows you to "emulate" the definition of class methods by defining instance methods on the Eigenclass:
class Greeting
def self.hello
'hello world!'
end
def self.eigenclass
class << self
self
end
end
end
Greeting.eigenclass # => #<Class:Greeting>
Greeting.eigenclass.name # => nil
Greeting.singleton_methods # => [:hello, :eigenclass]
Greeting.eigenclass.instance_methods(false) # => [:hello, :eigenclass]
First, we define a Greeting.eigenclass method. This method returns self in the context of the eigenclass — by using the class << self ... end syntax. In this case, self contains an unnamed instance of the class Class (a.k.a an anonymous class). This anonymous class keeps track of the class to which it is attached — the Greeting class in our case.
Then, we can see that the singleton methods of the Greeting class are the instance methods of the Greeting eigenclass.
Feel free to have a look to this very detailed article to learn more about this concept.
To illustrate #Sébastien P.'s answer:
dice = [1,2,3,4,5,6] #an ordinary array instance
def dice.throw #now it has an extra
sample
end
p dice.throw #=>3
So, I've been studying Ruby for over two weeks now and I'm having some issues understanding the whole OOP thing.
In this lesson, in the exercises in the end, we are asked to create a superclass of vehicle and add non-specific behavior to it, and then create a MyCar and a MyTruck subclasses that inherit from it and also have a constant that separates them. So I did like so:
class Vehicle
attr_accessor :color, :curr_speed
attr_reader :year, :model
def initialize(y, c, m)
#year = y
#color = c
#model = m
end
#SOME OTHER METHODS
def to_s
"My #{VEHICLE_TYPE} is a #{self.model} #{self.year} of color #{self.color}."
end
end
class MyCar < Vehicle
VEHICLE_TYPE = 'car'
end
class MyTruck < Vehicle
VEHICLE_TYPE = 'truck'
end
I also redefined the to_s method so that it would return a string that would say what kind of vehicle it is along with the other info. Now, the exercise does not ask us to do that -- in fact, they define a to_s method for MyCar and another to MyTruck that starts with "My car..." or "My truck..." but I feel like this goes against the DRY principle.
Thing is, it seems that Ruby does not accept a subclass variable passed in a superclass method. If I use #{VEHICLE_TYPE} it throws a uninitialized constant Vehicle::VEHICLE_TYPE (NameError), and if I use #{self.VEHICLE_TYPE} it throws a undefined method 'VEHICLE_TYPE' for Vehicle:Class (NoMethodError).
Am I correct in my assumption that Ruby does not accept a subclass variable in a superclass? And how could I go about to fix this issue in a similar fashion? Because I thought about simply adding another parameter to initizalize for type, store in a superclass instance variable and be done with it, but I don't think it would serve the purpose of the exercise.
And bear in mind that I'm a newbie!
Thanks in advance!
That's right. The superclass can't use the shortcut notation of VEHICLE_TYPE to access the constant you've defined.
When you want to access a constant outside of the class it is defined in, you can access it using a qualified name like:
Car::VEHICLE_TYPE
You were getting pretty close on your self.VEHICLE_TYPE attempt. But to provide a generic replacement for something like Car::, you'd need to use self.class::.
So your to_s method would look like:
def to_s
"My #{self.class::VEHICLE_TYPE} is a #{self.model} #{self.year} of color #{self.color}."
end
This will work as long as each instantiable class defines that constant.
I've been reading a lot about ruby classes vs objects and I came to this conclusion
There is a concept called "class" and we have the following classes:
BasicObject
which is the superclass of
Object
which is the superclass of
Module
which is the superclass of
Class
so:
the "class" Class is a subclass of "class" Object
Because all of the above "Class, Module, Object, Basic Object" are instances of "class" the concept. Instance_of? Class will
return true for all them
On the other hand (Object.new).instance_of? Class will return false, because (Object.new) is an instance of "class" Object
questions:
Class.is_a? Object is true because Class is a subclass of Object but Object.is_a? Class returns true as well, is that because Class here refers to the bigger class concept? If so why? isn't that confusing? How would I know which class is which?
You have several things wrong.
(2.) The reason Class, Module, Object, and Basic Object are instances of Class is not because Class < Module < Object < BasicObject. It has nothing to do with it.
(3.) (Object.new).instance_of? Class returns false not because Object.new is an instance of Object. It is because it is not an instance of Class.
Class.is_a? Object is true not because [the mentioned] Class is a subclass of Object. It is because (the mentioned) Class is an instance of Class (which is not mentioned), which is a subclass of Object.
The answer to the question is: Object.is_a? Class returns true because Object is an instance of Class.
If you want to know the class of an instance, use instance_of? or class methods.
3.is_a?(Object) # => false
3.is_a?(Fixnum) # => true
3.class # => Fixnum
What's really going in is that Ruby is cheating. Matz wanted to copy the elegance of smalltalk when he designed Ruby, namely the rule
Everything is an object.
To put that more technically
Everything is an instance of the Object class or one of its subclasses.
However, as you've seen, that simple rule leads to some confusing situations. How does all of that craziness work? Like I said, it cheats. The Ruby interpreter is hard coded to lie about certain relationships so that the golden rule of "everything is an object" looks like it's unbroken. Here it is straight from the source:
void Init_class_hierarchy(void)
{
/* the normal hierarchy we know and love */
rb_cBasicObject = boot_defclass("BasicObject", 0);
rb_cObject = boot_defclass("Object", rb_cBasicObject);
rb_cModule = boot_defclass("Module", rb_cObject);
rb_cClass = boot_defclass("Class", rb_cModule);
/* sneaky stuff to force consistent behavior!!! */
rb_const_set(rb_cObject, rb_intern_const("BasicObject"), rb_cBasicObject);
RBASIC_SET_CLASS(rb_cClass, rb_cClass);
RBASIC_SET_CLASS(rb_cModule, rb_cClass);
RBASIC_SET_CLASS(rb_cObject, rb_cClass);
RBASIC_SET_CLASS(rb_cBasicObject, rb_cClass);
}
And there are a lot more cases in the source code where built in classes need special treatment in order to give the "least surprising" result. Basically when it comes down to abstract internal stuff like this, don't worry about it. Just assume that things will behave as expected.
Can anyone explain to me what the meaning of adding self to the method definition is? Is it similar to the this keyword in java?
Contrary to other languages, Ruby has no class methods, but it has singleton methods attached to a particular object.
cat = String.new("cat")
def cat.speak
'miaow'
end
cat.speak #=> "miaow"
cat.singleton_methods #=> ["speak"]
def cat.speak creates a singleton method attached to the object cat.
When you write class A, it is equivalent to A = Class.new :
A = Class.new
def A.speak
"I'm class A"
end
A.speak #=> "I'm class A"
A.singleton_methods #=> ["speak"]
def A.speak creates a singleton method attached to the object A. We call it a class method of class A.
When you write
class A
def self.c_method
'in A#c_method'
end
end
you create an instance of Class(*). Inside the class definition, Ruby sets self to this new instance of Class, which has been assigned to the constant A. Thus def self.c_method is equivalent to def cat.speak, that is to say you define a singleton method attached to the object self, which is currently the class A.
Now the class A has two singleton methods, that we commonly call class methods.
A.singleton_methods
=> ["c_method", "speak"]
(*) technically, in this case where A has already been created by A = Class.new, class A reopens the existing class. That's why we have two singleton methods at the end. But in the usual case where it is the first definition of a class, it means Class.new.
In ruby self is somewhat similar to this in java, but when it comes to classes its more like the keyword static in java. A short example:
class A
# class method
def self.c_method
true
end
# instance method
def i_method
true
end
end
A.c_method #=> true
A.i_method #=> failure
A.new.i_method #=> true
A.new.c_method #=> failure
Update: Difference between static methods in java and class methods in ruby
Static methods in Java have two distinct features that makes them different from instance methods: a) they are static, b) they are not associated with an instance. (IOW: they really aren't like methods at all, they are just procedures.) In Ruby, all methods are dynamic, and all methods are associated with an instance. In fact, unlike Java where there are three different kinds of "methods" (instance methods, static methods and constructors), there is only one kind of method in Ruby: instance methods. So, no: static methods in Java are completely unlike methods in Ruby. – Jörg W Mittag 1 hour ago
When declaring a method, the self of the declaration is the declaring class/module, so effectively you are defining a class method. For the client, this works similar to a static method in java. The client would call the method on the class instead of an instance: MyClass.method
Here you can find some more details on class and instance methods.
EDIT: While the self keyword is akin to the this keyword in java, the effects of using self for class method declaration are similar to the effect of using the static keyword in java. The similarity is that static methods in java, like class methods in ruby are accessed using the class object iself instead of an instance of the class.
Please note that static does not stand for the opposite of dynamic. The choice of the name for this keyword is questionable (probably inherited from C) and rather should have been called perClass or similar to better reflect the meaning. The technical meaning is that all static members exist only once for each classloader.
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/