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
What's the Difference Between Equal, Eql, ===, and ==
How to Track System-Specific Config Files in a Repo/Project
How to Set Tls Context Options in Ruby (Like Openssl::Ssl::Ssl_Op_No_Sslv2)
How to Get a Specific Output Iterating a Hash in Ruby
Group Hashes by Keys and Sum the Values
How to Remove Emoji from String
Cannot Load Such File - Zlib Even After Using Rvm Pkg Install Zlib
Difference Between Attr_Accessor and Attr_Accessible
Ruby Array Access 2 Consecutive(Chained) Elements At a Time
Ruby Multiline Block Without Do End
How to Have Methods Inside Methods