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 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.
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 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.
How and why should I avoid using self in a Ruby method declaration
There's nothing wrong with using self, but it bypasses the requirement to create a variable instance of your object, so some die-hard OO programmers would suggest avoiding self for that reason. If you avoid "self" then you are forced to initialize your class and assign it to a variable name which forces you think of it as a true object, and not just a collection of functions.
Here's an example class to demonstrate how you would call methods with and without "self"
class StaticVersusObjectMethod
def self.class_method
puts 'Hello, static class method world!'
end
def object_method
puts 'Hello, object-oriented world!'
end
end
# No need to create an object instance variable if the method was defined with 'self'
StaticVersusObjectMethod.class_method
# You must create an object instance variable to call methods without 'self'
object = StaticVersusObjectMethod.new
object.object_method
output:
Hello, static class method world!
Hello, object-oriented world!
Whether you use self in the declaration should depend on the data you want your method to use. If the methods will only operate on the variables you pass in as parameters, then use 'self'. On the other hand, don't use 'self' if you want them to act as true object methods. "True" object methods can operate on the state of the class variables (fields) in the objects which you create and assign to a one or more variable names.
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.
ruby should I use self. or @
When you use @lines
, you are accessing the instance variable itself. self.lines
actually goes through the lines
method of the class; likewise, self.lines = x
goes through the lines=
method. So use @
when you want to access the variable directly, and self.
when you want to access via the method.
To directly answer your question, normally you want to set the instance variables directly in your initialize
method, but it depends on your use-case.
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.
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
Related Topics
How to Convert a String to a Constant in Ruby
To Use Self. or Not.. in Rails
Running Another Ruby Script from a Ruby Script
Stop Devise from Clearing Session
How to Update Ruby to 1.9.X on Mac
Rails: Specified 'Mysql2' for Database Adapter But the Gem Is Not Loaded
How to Install Ruby-Debug When Needing Necessary Libraries And/Or Headers
What Is the "Right" Way to Iterate Through an Array in Ruby
Correctly Doing Redirect_To :Back in Ruby on Rails When Referrer Is Not Available
Find Key/Value Pairs Deep Inside a Hash Containing an Arbitrary Number of Nested Hashes and Arrays
When Do I Need to Restart Server in Rails
Why Isn't Current Directory on My Ruby Path
Why Do Two Strings Separated by Space Concatenate in Ruby
Libmysqlclient.So.15: Cannot Open Shared Object File: No Such File or Directory