When to Use 'Self.Foo' Instead of 'Foo' in Ruby Methods

When to use `self.foo` instead of `foo` in Ruby methods

  1. It is idiomatic to prefer to omit self. when invoking methods; it is generally never needed.

  2. You must use self.foo = xxx when calling a setter method, instead of foo = 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 use self.do_something to invoke the method, as just do_something will end up reading the variable.
  3. You cannot use self.foo(...) to call a private method; you must instead call just foo(...).

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



Leave a reply



Submit