Can Someone Please Explain Class << Self to Me

Can someone please explain class self to me?

In Ruby, class << foo opens up the singleton class of the object referenced by foo. In Ruby, every object has a singleton class associated with it which only has a single instance. This singleton class holds object-specific behavior, i.e. singleton methods.

So, class << self opens up the singleton class of self. What exactly self is, depends on the context you are in, of course. In a module or class definition body, it is the module or class itself, for example.

If all you are using the singleton class for, is defining singleton methods, there is actually a shortcut for that: def foo.bar.

Here's an example of how to use singleton methods to provide some "procedures" which don't really have any association with a particular instance:

class << (Util = Object.new)
def do_something(n)
# ...
end
end

Util.do_something(n)

what does class self mean in Rails?

That is the same as

class Post < ActiveRecord::Base

def self.search(q)
# Class Level Method
# search from DB
end

def search2(qq)
# Instance Level Method
# search from DB
end
end

Class methods work on the class (e.g. Post), instance methods works on instances of that class (e.g. Post.new)

Some people like the class << self; code; end; way because it keeps all class level methods in a nice block and in one place.

Others like to prefix each method with self. to explicitly know that is a class method not an instance method. It's a matter of style and how you code. If you put all class methods in a block like class << self, and this block is long enough, the class << self line might be out of your editor view making it difficult to know that you are in the class instance block.

On the other hand, prefixing each method with self. and intermixing those with instance methods is also a bad idea, how do you know all the class methods while reading your code.

Pick an idiom which you prefer for your own code base but if you work on an open source project or you collaborate on someone else's code, use their code formatting rule.

What is self in class self and why is this different from the Class instance that is defining this block of code?

Why is self not the same as MyClass inside of the class << self scope.

Because the class keyword always changes the scope:

class MyClass
puts self #=> MyClass

class <<self
puts self #=>MyClass’s singleton class
end
end

More specifically, why is the method delegate not available to self
inside of class << self?

class MyClass

def self.delegate
puts "executing MyClass.delegate()"
end

class <<self
delegate
end

end

--output:--
1.rb:8:in `singleton class': undefined local variable or method `delegate' for #<Class:MyClass> (NameError)
from 1.rb:7:in `<class:MyClass>'
from 1.rb:1:in `<main>'

Note that the following constructs are equivalent:

class MyClass

def self.delegate
puts "executing MyClass.delegate()"
end

end

MyClass.delegate

--output:--
executing MyClass.delegate()

and:

class MyClass

class <<self
def delegate
puts "executing MyClass.delegate()"
end
end

end

MyClass.delegate

--output:--
executing MyClass.delegate()

Therefore, your code is equivalent to:

class MyClass

class <<self
def delegate
puts "executing MyClass.delegate()"
end

delegate
end

end

If you ignore the outer MyClass for a moment, then you defined a class like this:

class <<self
def delegate
puts "executing MyClass.delegate()"
end

delegate
end

That same structure can be replicated like this:

class Dog
def bark
puts “woof”
end

bark
end

which will produce the same type of error:

1.rb:7:in `<class:Dog>': undefined local variable or method `bark' for Dog:Class (NameError)
from 1.rb:1:in `<main>'
  1. When you call a method and you don't specify a receiver, ruby uses whatever object is currently assigned to the self variable as the receiver.

  2. Inside a method, ruby assigns the object that called the method to the self variable. The object that called the method is not the same thing as the class (object) in which the method is defined.

  3. Inside a class, but outside of any method definitions, ruby assigns the class (object) to self.

Note that it is the instances of the Dog class that can call the def's inside the Dog class, e.g. bark(). Similarly, it is the instances of the singleton class that can call the def's inside the singleton class, e.g. delegate()--the singleton class itself cannot call the def's inside the singleton class. The whole reason they are called singleton classes is because singleton classes have only one instance--in your case the one instance of the singleton class is MyClass. As a result, MyClass can call delegate(), but the singleton class cannot call delegate().

I don't understand really what a class method on an eignclass is
however.

Personally, I don't use the term eigenclass. In my opinion, ruby has made a decision that the term is singleton class. If you look through the docs for the Object class, there are no method names that have eigenclass in them, yet there are method names with singleton class in them.

All objects have a singleton class. A singleton class is an object. Therefore, every singleton class also has a singleton class--which means that the chain of singleton classes is infinite:

class Dog
end

s1 = Dog.singleton_class
puts s1

s2 = s1.singleton_class
puts s2

s3 = s2.singleton_class
puts s3

--output:--
#<Class:Dog>
#<Class:#<Class:Dog>>
#<Class:#<Class:#<Class:Dog>>>

Which means you can do stuff like this:

class Dog
class <<self #s1
class <<self #s2
def greet #Instances of s2 can call greet, and the only instance of s2 is s1.
puts "hello"
end
end
end
end

class Dog
class <<self
#Inside here self = Dog's singleton class = s1
greet #equivalent to Dogs_singleton_class.greet
end
end

--output:--
hello

However, I've never seen anyone use a singleton class of a singleton class (s2) before in their code. I did it once to answer a question a long, long time ago, and nobody had any idea what I was talking about.

There are some method lookup diagrams here, which might prove useful.

Difference between 'self.method_name' and 'class self' in Ruby

The class << self notation opens up the eigenclass of an object. An eigenclass is an anonymous class that stores instance-specific behaviour. In the case of a class an eigenclass is sometimes called a metaclass.

Ruby uses eigenclasses to implement so called 'class methods' (also called static methods).

A Class (as moritz stated) is also an Object in Ruby and in so far as it is an object it also has a class. The class of a class in Ruby is called Class.

A 'class method' in any language is a method in which a class is the receiver - that is the method is directly invoked on the class itself.

However in order for a method to be invoked on a receiver that method must be defined on the class of that receiver. In the case of classes a 'class method' could be implemented as an instance method on the Class class.

But defining an instance method on Class would mean that ALL classes get access to that class method which is not ideal.

Enter the eigenclass, as stated before, the eigenclass for an object is a special class that stores the methods unique to that object. In the case of classes the eigenclass subclasses the Class class and is the direct class of the class.

'class methods' in Ruby therefore are just 'instance methods' defined on the class's eigenclass.

The def MyClass.my_method notation actually defines my_method on the eigenclass of MyClass. If you use this notation you can get by (for a while) without actually understanding eigenclasses since you can trick yourself into thinking it is just Ruby's way of defining 'static methods' and continue thinking Ruby's class model is similar to Java's. However, the class << self notation allows no such interpretation and you must come to terms with the reality of eigenclasses.

In summary, 'class methods' are actually 'instance methods' defined on the eigenclass and the class << self gives you access to the eigenclass.

For more reading check out these links:

http://banisterfiend.wordpress.com/2008/11/25/a-complete-ruby-class-diagram/

http://banisterfiend.wordpress.com/2008/10/25/the-secret-life-of-singletons/

http://www.klankboomklang.com/2007/09/21/the-singleton-class/

class self vs self.method with Ruby: what's better?

class << self is good at keeping all of your class methods in the same block. If methods are being added in def self.method form then there's no guarantee (other than convention and wishful thinking) that there won't be an extra class method tucked away later in the file.

def self.method is good at explicitly stating that a method is a class method, whereas with class << self you have to go and find the container yourself.

Which of these is more important to you is a subjective decision, and also depends on things like how many other people are working on the code and what their preferences are.

class method `self.` within class methods block `class self` in Ruby

Each object in Ruby has its own singleton class. This is where all the methods of instances are defined.

Consider the following example.

class C; end
c1, c2 = C.new, C.new
c1.extend(Module.new { def m1; 42; end })

c1.m1
#⇒ 42
c2.m1
#⇒ NoMethodError: undefined method `m1' for #<C:0x000055cb062e6888>

c1.singleton_class.instance_methods.grep /m1/
#⇒ [:m1]
c2.singleton_class.instance_methods.grep /m1/
#⇒ []

Singleton class is needed to make it possible to extend objects etc.

In Ruby, everything is object. Classes are indeed objects as well. That’s why each class has its own singleton class. And each singleton class has its singleton class.

c1.singleton_class.singleton_class.singleton_class.singleton_class
#⇒ #<Class:#<Class:#<Class:#<Class:#<C:0x000055cb0459c700>>>>>

Methods defined on foo are stored in the singleton class of foo. Methods defined on foo’s singleton class are stored in the singleton class of the singleton class of foo. And so forth.

It’s not quite practical, but it’s still possible due to how Ruby treats everything as Object.

Yield in class self in class method

It's a little bit weird, but OK if you are exploring Ruby.

class Person
puts "evaluating Person's body ..."
def self.mega_methods
puts 'in Person#self.mega_methods, about to yield ...'
yield
end
end

class Tom < Person
puts "evaluating Tom's body ..."
print 'Tom.singleton_methods : '; p Tom.singleton_methods
mega_methods do
puts 'in Tom, about to define self.hiya!'
def self.hiya!
puts 'hiYA!'
end
end
print 'Tom.singleton_methods : '; p Tom.singleton_methods
end

Tom.hiya!

Execution :

$ ruby -w t.rb 
evaluating Person's body ...
evaluating Tom's body ...
Tom.singleton_methods : ["mega_methods"]
in Person#self.mega_methods, about to yield ...
in Tom, about to define self.hiya!
Tom.singleton_methods : ["mega_methods", "hiya!"]
hiYA!

Note that the exclamation point in the name of a method is, by convention, reserved for destroying methods, such as String#sub! which modifies the receiver string.

See also What does def `self.function` name mean?

It's all about self !

class Person2
def self.mega_methods
print 'in Person2 self='; p self
class << self
print 'in class << self self='; p self
yield
end
end
end

class Tom2 < Person2
mega_methods do
puts "in Tom2, about to define self.hiya! for self=#{self}"
def self.hiya!
puts 'hiYA!'
end
def hi
puts 'hi'
end
end
end

print 'Tom2.singleton_methods : '; p Tom2.singleton_methods
print 'Tom2.instance_methods : '; p Tom2.instance_methods(false)
Tom2.hiya!
Tom2.new.hi

Execution :

$ ruby -w t2.rb 
in Person2 self=Tom2
in class << self self=#<Class:Tom2>
in Tom2, about to define self.hiya! for self=Tom2
Tom2.singleton_methods : ["mega_methods", "hiya!"]
Tom2.instance_methods : ["hi"]
hiYA!
hi

Why isn't the eigenclass equivalent to self.class, when it looks so similar?

class << self is more than just a way of declaring class methods (though it can be used that way). Probably you've seen some usage like:

class Foo
class << self
def a
print "I could also have been defined as def Foo.a."
end
end
end

This works, and is equivalent to def Foo.a, but the way it works is a little subtle. The secret is that self, in that context, refers to the object Foo, whose class is a unique, anonymous subclass of Class. This subclass is called Foo's eigenclass. So def a creates a new method called a in Foo's eigenclass, accessible by the normal method call syntax: Foo.a.

Now let's look at a different example:

str = "abc"
other_str = "def"

class << str
def frob
return self + "d"
end
end

print str.frob # => "abcd"
print other_str.frob # => raises an exception, 'frob' is not defined on other_str

This example is the same as the last one, though it may be hard to tell at first. frob is defined, not on the String class, but on the eigenclass of str, a unique anonymous subclass of String. So str has a frob method, but instances of String in general do not. We could also have overridden methods of String (very useful in certain tricky testing scenarios).

Now we're equipped to understand your original example. Inside Foo's initialize method, self refers not to the class Foo, but to some particular instance of Foo. Its eigenclass is a subclass of Foo, but it is not Foo; it couldn't be, or else the trick we saw in the second example couldn't work. So to continue your example:

f1 = Foo.new(:weasels)
f2 = Foo.new(:monkeys)

f1.weasels = 4 # Fine
f2.monkeys = 5 # Also ok
print(f1.monkeys) # Doesn't work, f1 doesn't have a 'monkeys' method.

Hope this helps.

self vs class name for class methods in inheritance

self is widely used in Ruby Metaprogramming.

From Metaprogramming Ruby book:

Every line of Ruby code is executed inside an object—the so–called
current object. The current object is also known as self, because
you can access it with the self keyword.

Only one object can take the role of self at a given time, but no
object holds that role for a long time. In particular, when you call a
method, the receiver becomes self. From that moment on, all instance
variables are instance variables of self, and all methods called
without an explicit receiver are called on self. As soon as your code
explicitly calls a method on some other object, that other object
becomes self.

So, in code:

class Dog
# self represents the class object i.e: Dog. Which is an instance of Class.
# `bark` will be treated as class method
def self.bark
print "woof"
end
end

can also be written as:

class Dog
# Dog is an instance of Class.
# `bark` will be treated as class method
def Dog.bark
print "woof"
end
end

Inheritance allows a subclass to use features of its parent class. That's why you can access bark method in Little_dog class since it is inherited Dog class:

class Little_dog < Dog
# has `bark` as a class method because of Dog
end

Ruby style guide tip: In Ruby it's considered as a best practice to use CamelCase convention for naming classes and modules.



Related Topics



Leave a reply



Submit