I’m currently reading The Well-Grounded Rubyist. In the section about
class variables, instance variables, and self they have this class as an
example:
class Car
@@makes = []
@@cars = {}
attr_reader :make
def self.total_count @total_count || 0
end
def self.total_count=(n) @total_count = n
end
def self.add_make(make)
unless @makes.include?(make)
@@makes << make
@@cars[make] = 0
end
end
def initialize(make)
if @@makes.include?(make)
puts “Creating a new #{make}!” @make = make
self.class.total_count += 1
else
raise “No such make: #{make}.”
end
end
def make_mates
@@cars[self.make]
end
end
My question is in the initialize method about the line:
self.class.total_count += 1
what is the purpose of the ‘class’ in that statement?
My question is in the initialize method about the line:
self.class.total_count += 1
what is the purpose of the ‘class’ in that statement?
self.class is (obviously) the class of self, so in this case it’s Car.
You may actually write Car.total_count, but then you’ll get trouble with
renaming and inheritance.
what is the purpose of the ‘class’ in that statement?
Since total_count is a method of class Car, inside the initialize method
of an instance you can refer to class Car as self.class. It would seem
simpler to say Car::total_count in this particular case.
so is self.total_count equal to self.class.total_count?
Nope. Assuming that “self” at that time is an individual Car,
self.total_count would be an instance variable on that Car.
self.class.total_count belongs to class Car, because that’s
self.class.
Think of it like a literal class, like in a classroom in school. Self
(in this situation) is an individual student. He doesn’t have a
total_count. But the class itself does.
so is self.total_count equal to self.class.total_count?
It depends where they are called. You need to know what self is at the
point where the call is made. Going back to your sample code…
[…]
So in answer to your question, Yes they are the same object.
No, they are never the same object. self.class in the context of Car is
not Car but Class, because the class of a class is Class.
The only context where self and self.class are the same is the context
of Class, because Class is an instance of itself.
so is self.total_count equal to self.class.total_count?
No, of course not. self refers to the particular instance of Car,
whereas self.class refers to the class of this instance, i. e. Car
itself. Those are two completely different objects.
Since the instances of Car don’t even have a total_count method, calling
self.total_count will throw an exception (try it yourself).
It’s important to distinguish between the methods of the class and the
methods of the instances. The Car class has three new methods:
total_count, total_count= and add_make. The instances of Car also have
three new methods: make_mates, initialize and make (the latter is
created by attr_reader).
No, they are never the same object. self.class in the context of Car is
not Car but Class, because the class of a class is Class.
The only context where self and self.class are the same is the context
of Class, because Class is an instance of itself.
Did you read what I wrote? I said, it depends where the calls are made.
I assumed the OP was asking the question based on the code that he
posted. The two calls were made in different parts of the code where
self were different objects.
1.9.3p125 :021 > class Car
1.9.3p125 :022?> # Here self == Car
1.9.3p125 :023 > p self
1.9.3p125 :024?>
1.9.3p125 :025 > def initialize
1.9.3p125 :026?> # Here self is an instance of Car so self.class
== Car
1.9.3p125 :027 > p self.class
1.9.3p125 :028?> end
1.9.3p125 :029?>
1.9.3p125 :030 > end
Car
=> nil
1.9.3p125 :031 >
1.9.3p125 :032 > Car.new
Car
=> #Car:0x007fcc1a3fca30
1.9.3p125 :033 >
self and self.class are both Car. Sure if they two calls were made in
the same context they would return different objects but, this isn’t the
case in the code the OP posted.
Henry
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.