When to use `self.foo` instead of `foo` in Ruby methods
It is idiomatic to prefer to omit
self.
when invoking methods; it is generally never needed.You must use
self.foo = xxx
when calling a setter method, instead offoo = xxx
, so that Ruby realizes that you are not trying create a new local variable.- Similarly, in the unlikely event that you have an existing local variable
do_something
with the same name as a method, you must useself.do_something
to invoke the method, as justdo_something
will end up reading the variable.
- Similarly, in the unlikely event that you have an existing local variable
You cannot use
self.foo(...)
to call a private method; you must instead call justfoo(...)
.
Difference between @foo, self.foo, and foo?
Why is self.songs used instead of @songs
Using the method is more flexible. You're abstracting yourself from knowing how exactly it gets/stores data. The less you rely on implementation details, the easier it will be for you to change code later.
One small example, consider this implementation of songs
def songs
@songs ||= []
@songs
end
@songs
may or may not have been assigned value prior to invocation of this method. But it doesn't care. It makes sure that @songs
does have a sane default value. The concept is called "lazy initialization" and it's very tedious and error-prone to do if you use instance variables directly.
So, when in doubt, always use methods.
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.
When do I need to call self.field = in Mongoid?
When you are assigning a value to a property of an instance you need to use self.
otherwise it creates a new local variable, in this case state
that is deleted once it is out of scope (the end of the method). When reading a property it look in the current scope and then walks up the tree, in this case finding state
on the instance.
When to use 'self' in Ruby
Whenever you want to invoke a setter method on self, you have to write self.foo = bar. If you just write foo = bar, the ruby parser recognizes that as a variable assignment and thinks of foo as a local variable from now on. For the parser to realize, that you want to invoke a setter method, and not assign a local variable, you have to write obj.foo = bar, so if the object is self, self.foo = bar
When do I need to use self.instance_method vs instance_method alone?
There are a few differences between self.foo(...)
and foo(...)
, but they're mostly equivalent.
Privacy
private
methods can only be called via foo
directly, and never with an explicit receiver. So if foo
is marked private
, then you have to call it without self
.
class Example
private def foo(x)
x + 1
end
def bar
foo # Works fine
self.foo # Error: foo is private
end
end
Shadowing
If you have a local variable called foo
in the current function, then writing foo
without arguments will reference the local variable instead
class Example
def foo(*args)
puts "Hello :)"
end
def bar
foo = 100 # Just an ordinary variable; no relation to the above method
foo # This refers to the local variable called "foo"
self.foo # This calls the method foo() with no arguments
foo(1) # This calls the method foo() with one argument
self.foo(1) # Equivalent to the above; calls with one argument
end
def baz
foo # There's no local variable called "foo", so this calls the method
end
end
Assignment
If the method you're talking about is an assignment method (i.e. ends in =
), then it must always be called with an explicit receiver
class Example
def foo=(value)
puts "Assigning foo = #{value}"
end
def bar
foo = 0 # This creates a new local variable called foo and assigns to it
self.foo = 0 # Calls foo= on self
end
end
Why is `class self` more common than `class Foo` for opening a class object's eigenclass?
When using class << Foo
, or when defining explicitly def Foo.some_method(args)
you are repeating the name of the class.
Using class << self
is DRYer, and makes refactoring easier (changing the class name is done in one place, and does not have to be repeated in the code), as well as copy+paste to other classes/projects.
class Foo1
# ..
end
class << Foo # <- :(
#..
end
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.
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.
In Ruby, how to write code inside a class so that getter foo and setter self.foo = ... look more similar?
Since local scope takes precedence, when you say foo = something
, a local variable foo
will be created and assigned the contents of something
.
The reason you can write foo
in order to use the getter is because Ruby will move up in scope when it can't find a variable with that name and it will eventually find the method.
If there is a local variable with the same name as the getter method, Ruby will use its value instead:
class Foo
attr_accessor :foo
def initialize
@foo = :one
end
def f
foo = :two
foo
end
end
Foo.new.f
# => :two
In order to make it clear that you want to access the setter, you must write self.foo = something
. That will tell Ruby you want to execute the foo=
method on the self
object with something
as parameter.
Related Topics
How to Convert a Bigdecimal to a 2-Decimal-Place String
Accepts_Nested_Attributes_For With Belongs_To Polymorphic
Saving Enum from Select in Rails 4.1
Using Helpers in Model: How to Include Helper Dependencies
How to Temporarily Redirect Stderr in Ruby
Paginating an Array in Ruby With Will_Paginate
Group Hashes by Keys and Sum the Values
When to Use 'Self.Foo' Instead of 'Foo' in Ruby Methods
Actioncontroller::Unknownformat
Why Are Gems Installed in a Directory With a Different Ruby Version Than I'M Running
Creating Matrix With 'Array.New(N, Array.New)'
What Does the "Map" Method Do in Ruby
Sort Hash by Key, Return Hash in Ruby