Class ≪≪ Self Idiom in Ruby

class self idiom in Ruby

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.

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 does self. mean in a class method?

Using syntax def receiver.method you can define methods on a specific objects.

class Dog
def bark
puts 'woof'
end
end

normal_dog = Dog.new
angry_dog = Dog.new


def angry_dog.bite
puts "yum"
end


normal_dog.class # => Dog
angry_dog.class # => Dog

angry_dog.bite # >> yum
normal_dog.bite # ~> -:15:in `<main>': undefined method `bite' for #<Dog:0x007f9a93064cf0> (NoMethodError)

Note that even though dogs are of the same class Dog, one of them has a unique method that another dog doesn't.

The same thing with classes. Inside of class definition, self points to that class. This is critical to understanding.

class Foo
self # => Foo
end

Now let's look at these two classes:

class Foo
def self.hello
"hello from Foo"
end
end

class Bar
end

Foo.class # => Class
Bar.class # => Class


Foo.hello # => "hello from Foo"
Bar.hello # ~> -:15:in `<main>': undefined method `hello' for Bar:Class (NoMethodError)

Even though both Foo and Bar are both instances (objects) of class Class, one of has a method which another doesn't. The same thing.

If you omit the self in method definition, then it becomes instance method and it will be available on instances of a class rather than on the class itself. See the Dog#bark definition in the first snippet.

For closing, here's a couple more methods of how you can define a class instance method:

class Foo
def self.hello1
"hello1"
end

def Foo.hello2
"hello2"
end
end

def Foo.hello3
"hello3"
end


Foo.hello1 # => "hello1"
Foo.hello2 # => "hello2"
Foo.hello3 # => "hello3"

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.

Why does self in class self refer to the class?

Inside methods self refers to the instance, inside class/module definition, but outside of any method — to the class/module itself.

class Thing
puts self.inspect
def foo
puts self.inspect
end
end
puts "==="
Thing.new.foo

Try the code above and you’ll likely see what’s happening there: the class is being parsed in the first place, and the first puts is being executed. Then puts "===" prints the "===" string out. And, afterwards, the instance is being printed from inside the method.

What does self mean in Ruby?

self refers to the object that is currently in context.

In your example, self is the class itself and def self.method is defining a class method. For example:

class MyClass
def self.method
puts "Hello!"
end
end

> MyClass.method
#=> "Hello"

You can also use self on instances of a class.

class MyClass
def method_a
puts "Hello!"
end

def method_b
self.method_a
end
end

> m = MyClass.new
> m.method_b
#=> "Hello!"

In this case, self refers to the instance of MyClass.

There is a good blog post on self in Ruby here, or, as it was pointed out in the comments, there is some more on this in the Ruby documentation.

When to use self for Ruby Class

The methods defined right inside a class block are instance methods:

class Foo
def bar
end
end

Methods defined within class << self inside a class block are class methods:

class Foo
class << self
def baz
end
end
end

Instance methods become available to any instance of a given class:

foo = Foo.new
foo.bar

Whereas class methods can be called directly on the class:

Foo.baz

Attempting to call instance methods on the class or vice versa results in an error:

Foo.bar #=> NoMethodError: undefined method `bar' for Foo:Class
foo.baz #=> NoMethodError: undefined method `baz' for #<Foo:0x00007ffe20055a20>

Another way to define class methods is by prefixing the method name with self.:

class Foo
def self.baz
end
end

You could also define them outside the class block, although this is rarely seen:

def Foo.baz
end

Or likewise:

class << Foo
def baz
end
end

Note that defining methods this way is not limited to classes. You can add methods to arbitrary objects, e.g.:

o = Object.new

def o.hello
"hello from o"
end

o.hello
#=> "hello from o"

Or via:

class << o
def hello
"hello from o"
end
end

Internally, these methods are added to the object's singleton class. It's a special purpose class to hold methods for just that instance:

o.singleton_class.instance_methods(false)
#=> [:hello]

For the Foo class above:

Foo.instance_methods(false)                 #=> [:bar]
Foo.singleton_class.instance_methods(false) #=> [:baz]

So technically, a class method is just an instance method defined on the class' singleton class.

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.

What is the 'self' keyword doing exactly in this Class method?

self is the class Restaurant. def self.method is how you implement a method on the class itself rather than an instance of the class. Restaurant.filter_by_city(...) rather than Restaurant.new.filter_by_city(...).

self changes in Ruby depending on context. Within a method, self is the object the method was called on.

Within the class Restaurant block, and outside of any method, self is the Restaurant object which is a Class object. Everything is an object in Ruby. Everything.

You can also do this by declaring a block where the class is the instance.

class << self
def filter_by_city(restaurants, city)
restaurants.select { |restaurant| restaurant.city == city }
end
end

Normally you'd use this syntax if you have a lot of class methods.

See Self in Ruby: A Comprehensive Overview for more.



Related Topics



Leave a reply



Submit