Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

class << self idiom in Ruby

What does class << self do in Ruby?

like image 371
randombits Avatar asked Mar 24 '10 03:03

randombits


People also ask

What does class << self do in Ruby?

In the above example, class << self modifies self so it points to the metaclass of the Zabuton class. When a method is defined without an explicit receiver (the class/object on which the method will be defined), it is implicitly defined within the current scope, that is, the current value of self.

What does << mean in Ruby?

In ruby '<<' operator is basically used for: Appending a value in the array (at last position) [2, 4, 6] << 8 It will give [2, 4, 6, 8] It also used for some active record operations in ruby.

What is self class in Ruby?

Class Method Self A class method is a method that refers only to that class in all contexts, but not to any individual instances of that class. A class instance method is a method that applies to all instances of that class, but not for the class object itself.

What is a singleton class in Ruby?

A singleton class of an object (or a class) is a class created by Ruby only for this specific object. This class is somehow “hidden” to us, but it is there. When calling a method on this object, Ruby will look first into its singleton class, if there is one, to find that method.


2 Answers

First, the class << foo syntax opens up foo's singleton class (eigenclass). This allows you to specialise the behaviour of methods called on that specific object.

a = 'foo' class << a   def inspect     '"bar"'   end end a.inspect   # => "bar"  a = 'foo'   # new object, new singleton class a.inspect   # => "foo" 

Now, to answer the question: class << self opens up self's singleton class, so that methods can be redefined for the current self object (which inside a class or module body is the class or module itself). Usually, this is used to define class/module ("static") methods:

class String   class << self     def value_of obj       obj.to_s     end   end end  String.value_of 42   # => "42" 

This can also be written as a shorthand:

class String   def self.value_of obj     obj.to_s   end end 

Or even shorter:

def String.value_of obj   obj.to_s end 

When inside a function definition, self refers to the object the function is being called with. In this case, class << self opens the singleton class for that object; one use of that is to implement a poor man's state machine:

class StateMachineExample   def process obj     process_hook obj   end  private   def process_state_1 obj     # ...     class << self       alias process_hook process_state_2     end   end    def process_state_2 obj     # ...     class << self       alias process_hook process_state_1     end   end    # Set up initial state   alias process_hook process_state_1 end 

So, in the example above, each instance of StateMachineExample has process_hook aliased to process_state_1, but note how in the latter, it can redefine process_hook (for self only, not affecting other StateMachineExample instances) to process_state_2. So, each time a caller calls the process method (which calls the redefinable process_hook), the behaviour changes depending on what state it's in.

like image 99
Chris Jester-Young Avatar answered Sep 30 '22 13:09

Chris Jester-Young


I found a super simple explanation about class << self , Eigenclass and different type of methods.

In Ruby, there are three types of methods that can be applied to a class:

  1. Instance methods
  2. Singleton methods
  3. Class methods

Instance methods and class methods are almost similar to their homonymous in other programming languages.

class Foo     def an_instance_method       puts "I am an instance method"     end     def self.a_class_method       puts "I am a class method"     end   end  foo = Foo.new  def foo.a_singleton_method   puts "I am a singletone method" end 

Another way of accessing an Eigenclass(which includes singleton methods) is with the following syntax (class <<):

foo = Foo.new  class << foo   def a_singleton_method     puts "I am a singleton method"   end end 

now you can define a singleton method for self which is the class Foo itself in this context:

class Foo   class << self     def a_singleton_and_class_method       puts "I am a singleton method for self and a class method for Foo"     end   end end 
like image 30
Saman Mohamadi Avatar answered Sep 30 '22 13:09

Saman Mohamadi