Table of contentsClick link to navigate to the desired location
This content has been automatically translated from Ukrainian.
In Ruby everything is an object (well, almost everything), even classes. And every object can have own unique methods, which do not belong to other instances of the same class.
Read what Proc and Lambda are in my previous post.
These methods are not stored in a regular class, but in a special hidden class called singleton class or eigenclass.
What is singleton class?
Singleton class is the "personal" class of a particular object. That's where Ruby stores methods that are defined for that object alone.
user1 = "Alice"
user2 = "Bob"
def user1.greet
"Hello, I'm #{self}!"
end
p user1.greet # => "Hello, I'm Alice!"
p user2.greet # => NoMethodError
Here, greet is a method that exists for user1 object only. Ruby created his own singleton class for user1 and put this method there.
How to see singleton_class?
Each object has a singleton_class method that allows you to access this "hidden" class:
user1.singleton_class # => #<Class:#<String:0x0000000103c4b8f0>>
If you define the method directly in this class, it will also become unique:
user = "Ruby"
user.singleton_class.class_eval do
def version
"3.2.1"
end
end
p user.version # => "3.2.1"
class << self
When you write class << self, you actually open the singleton class of the current object. This is a convenient syntax for defining methods within it.
Example 1: In a conventional object
user = "John"
class << user
def greet
"Hi, I'm #{self}"
end
end
p user.greet # => "Hi, I'm John"
Example 2: in a class (definition of class methods)
class Person
class << self
def species
"Human"
end
end
end
p Person.species # => "Human"
Ruby just opened singleton class for the class itself Person and added the species method there.
In short:
- In Ruby each object has its own singleton class - a hidden class for its unique methods.
- The method def obj.method or class << obj adds the method to the singleton class of this object.
- You often use it unconsciously when you write class methods (class << self) or unique methods for a single object.
But for consolidation, we will consider the issue. Is it possible to call the singleton method of a class on its object? NO. It will not be available at the classroom facility (that is, on an instance).
In the example:
class Person
class << self
def species
"Human"
end
end
end
Ruby creates class method, that is, the method that lives in singleton class of the Person class itself, not in Person's instance methods.
Therefore:
Person.species # => "Human" Person.new.species # => NoMethodError
Explanation:
- Person is a Class object.
- class << self opens singleton class for this object (Person).
- The species method is stored there.
- Instances of Person.new (created class objects) do not see it, because they look for methods in the regular Person class, and not in its singleton class.
If you want the method to be available and how classy, and how exemplary, can be simply defined twice or taken out in module:
class Person
def self.species
"Human"
end
def species
"Human"
end
end
Person.species # => "Human"
Person.new.species # => "Human"
Or more elegant - through module:
model Species
def species
"Human"
end
end
class Person
extend Species # adds the method as a class method
include Species # adds method as instance
end
This post doesn't have any additions from the author yet.