How to use Ruby's self keyword
In most cases self.foo
is indeed redundant because you can just write foo
for the same effect, but in this case it is not and the self
is required.
var_one = method(args)
will create a local variable called var_one
, it will not call any method or do anything else to self
.
self.var_one = method(args)
will call the method var_one=
on self
with the argument method(args)
.
Another case where the use of self
is non-optional would be if you want to pass it as an argument to a method, i.e. some_method(self)
- you can't do that without the self
keyword.
To use self. or not.. in Rails
def self.method_name
end
defines a class method.def method_name
end
defines an instance method.This is a pretty good post on it.
How to use the Ruby self keyword
Usually, self
as a receiver can be omitted, and in such cases, it is usually preferable to do so. However, there are a few cases when omitting self
make the code mean something else.
One such case is, as in your example
self.name = ...
, using a setter method. Ruby's syntax is ambiguous between method and variable call, and when something that can be interpreted either as a variable or a method is followed by=
, its interpretation as a local variable assignment has priority.Another case is when you want to call the method
class
. There is also the keywordclass
, and interpretation ofclass
as the keyword has priority over it as the method.Still another case is when you want to use the method
[]
. This notation is also used for array literal, and interpretation of it as an array has priority over it as a method.
self
. The other way is to write ()
after the method.Regarding your example self.each_with_index ...
, the self
can be omitted, and not doing so is not a recommended practice.
When to use self in Model?
When you're doing an action on the instance that's calling the method, you use self.
With this code
class SocialData < ActiveRecord::Base
def set_active_flag(val)
active_flag = val
save!
end
end
You are defining a brand new scoped local variable called active_flag, setting it to the passed in value, it's not associated with anything, so it's promptly thrown away when the method ends like it never existed.self.active_flag = val
However tells the instance to modify its own attribute called active_flag, instead of a brand new variable. That's why it works. 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.
When to use self in module's methods
Use self
in each method definition if you want the methods to be defined only in the singleton class of the module (where the methods defined using self
live). Omit self and extend self
if you want the methods of the module to be defined as instance methods and singleton methods at the same time.
For instance, you can call the method using RG::Stats.sum(array)
and still have it listed by the instance_methods
method if you do this:
module RG::Stats
extend self
def sum(a, args = {})
a.inject(0){ |accum, i| accum + i }
end
end
This way, the sum
method is defined as an instance method and it is included in the singleton class of the module after using extend self
.You can check the instance methods of RG::Stats
module to verify this:
RG::Stats.instance_methods
=> [:sum]
With this technique you don't have to worry about defining the method without the self
keyword because modules can't have instances so it cannot be called like an instance method of RG::Stats
module. It can only be called as a singleton method RG::Stats.sum(array)
thanks to the extend self
statement. 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.
In Ruby, when should you use self. in your classes?
Use self when calling a class's mutator. For example, this won't work:
class Foo
attr_writer :bar
def do_something
bar = 2
end
end
The problem is that 'bar = 2' creates a local variable named 'bar', rather than calling the method 'bar=' which was created by attr_writer. However, a little self
will fix it:class Foo
attr_writer :bar
def do_something
self.bar = 2
end
end
self.bar = 2
calls the method bar=
, as desired.You may also use self to call a reader with the same name as a local variable:
class Foo
attr_reader :bar
def do_something
bar = 123
puts self.bar
end
end
But it's usually better to avoid giving a local variable the same name as an accessor. What is the value of self in a Rails model and why aren't obvious instance methods available?
Inside of an instance method self
is that instance. However, when you call a method with explicit receiver, then ruby's visibility control kicks in and forbids invocation of the private method.
class Foo
def implicit
self # => #<Foo:0x007fc019091060>
private_method
end
def explicit
self # => #<Foo:0x007fc019091060>
self.private_method
end
private
def private_method
"bar"
end
end
f = Foo.new
f.implicit # => "bar"
f.explicit # =>
# ~> -:9:in `explicit': private method `private_method' called for #<Foo:0x007fc019091060> (NoMethodError)
# ~> from -:25:in `<main>'
If you want to call private methods, use implicit receiver or send
.self.send :private_method
Update
An excerpt from a ruby metaprogramming book.
What private Really Means
Now that you know about self, you can cast a new light over Ruby’s private keyword. Private methods are governed by a single simple rule: you cannot call a private method with an explicit receiver. In other words, every time you call a private method, it must be on the implicit receiver—self. Let’s see a corner case:
class C
def public_method
self.private_method
end
private
def private_method; end
end
C.new.public_method
⇒ NoMethodError: private method ‘private_method' called [...]
You can make this code work by removing the self keyword.
This contrived example shows that private methods come from two rules working together: first, you need an explicit receiver to call a method on an object that is not yourself, and second, private methods can be called only with an implicit receiver. Put these two rules together, and you’ll see that you can only call a private method on yourself. You can call this the “private rule.”
You could find Ruby’s private methods perplexing—especially if you come from Java or C#, where private behaves very differently. When you’re in doubt, just go back to the private rule, and everything will make sense. Can object x call a private method on object y if the two objects share the same class? The answer is no, because no matter which class you belong to, you still need an explicit receiver to call another object’s method. Can you call a private method that you inherited from a superclass? The answer is yes, because you don’t need an explicit receiver to call inherited methods on yourself.
Related Topics
Case Insensitive Search in Rails
Regex That Matches Valid Ruby Local Variable Names
How to Tell Unicorn to Understand Heroku's Signals
Define_Method with Predefined Keyword Arguments
Rails for Zombies Lab 4 > Exercise 3
Recording Audio Through Rtmp/Rails
Rails 4 - Devise: Getting Actioncontroller::Unknownformat on Signup
Automating Ssh to Windows with Ruby
Modifying Text Inside HTML Nodes - Nokogiri
Ruby Class#New - Why Is 'New' a Private Method
Easiest Way to Convert "A/B/C" to ["A/B/C", "A/B", "A"]
Current Password Can't Be Blank When Updating Devise Account
How to Declare a Two-Dimensional Array in Ruby
Using Elasticsearch to Filter Through Tags with Whitespace
Openssl::Ssl::Sslerror Ubuntu 12.04 Only
How to Get Content from a Website Using Ruby/Rails