I feel I should add a little here. I’ll do it illustratively using code
examples, hopefully people can understand the underlying message.
- Define a method in a class, create an instance, and call the method
on the instance.
# Define a method
# Inside that method, ‘self’ refers to the instance object.
my_foo = Foo.new
my_foo.asd #=> “#Foo:0x007fec18284568”
We can’t do things like
Foo.asd, because we haven’t added a class
method to Foo.
- A couple of ways of defining class methods:
Open the class ‘Foo’
Inside the class definition (but not inside methods),
‘self’ refers to the class object.
# Define a class method
# Inside it, ‘self’ refers to the class object.
Foo.asd #=> “Foo”
Like above, but we don’t rely on the word ‘self’
to refer to the class object.
Bar.asd #=> “Bar”
Like above, but doing things in different scopes.
Baz.asd #=> “Baz”
…etc. Note that you can use ‘def obj.meth’ to arbitrarily define
methods directly on the ‘obj’ (whether or not obj is called ‘self’ or
What this actually does is define the method on obj’s singleton class,
which you can think of as a magic class that has exactly one instance:
It might help, at this point, to remember a couple of things:
class Foo; end opens (or reopens) the definition of class Foo
- the word ‘Foo’ in your code is a constant, and the value of that
constant is an object, and that object is_a? Class
- this also works: Foo = Class.new
So ‘Foo’ is just another object, and when you call ‘Foo.blah’ ruby
- Foo.singleton_class, for any methods defined directly on Foo, like
- Foo’s class, Class, for any instance methods defined there, like
- … and on up the inheritance tree, through Module, Object, Kernel,
It is possible to open (or reopen) an object’s singleton class using a
special extension syntax:
qux = Object.new
class << qux
qux.asd #=> "#Object:0x007fec182ffdd0
Note that this is essentially the same as
def qux.asd, but we can do
other things between the ‘class <<’ and the ‘end’, e.g.:
class << qux
qux.bob = 123
qux.bob #=> 123
qux.asd #=> NoMethodError: private method `asd’ called for
Now, combining this with the fact that a class is just another object,
we can do:
class << self
Qux.bob = 123
Qux.bob #=> 123
Qux.asd #=> NoMethodError: private method `asd’ called for Qux:Class
Note that, unless we explicitly write the word ‘Class’ in the code, or
do some other horrible hackery, we’re never adding instance methods to
the Class class. You could do the following:
… which would make the following all work:
Foo.banana #=> “yes please”
Bar.banana #=> “yes please”
Integer.banana #=> “yes please”
Class.banana #=> “yes please”
But that’s different from defining ‘self.meth’ inside a class
Hope that makes sense.