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 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.
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 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
What is self in class self and why is this different from the Class instance that is defining this block of code?
Why is self not the same as MyClass inside of the class << self scope.
Because the class keyword always changes the scope:
class MyClass
puts self #=> MyClass
class <<self
puts self #=>MyClass’s singleton class
end
end
More specifically, why is the method delegate not available to self
inside of class << self?class MyClass
def self.delegate
puts "executing MyClass.delegate()"
end
class <<self
delegate
end
end
--output:--
1.rb:8:in `singleton class': undefined local variable or method `delegate' for #<Class:MyClass> (NameError)
from 1.rb:7:in `<class:MyClass>'
from 1.rb:1:in `<main>'
Note that the following constructs are equivalent:
class MyClass
def self.delegate
puts "executing MyClass.delegate()"
end
end
MyClass.delegate
--output:--
executing MyClass.delegate()
and:
class MyClass
class <<self
def delegate
puts "executing MyClass.delegate()"
end
end
end
MyClass.delegate
--output:--
executing MyClass.delegate()
Therefore, your code is equivalent to:
class MyClass
class <<self
def delegate
puts "executing MyClass.delegate()"
end
delegate
end
end
If you ignore the outer MyClass for a moment, then you defined a class like this:
class <<self
def delegate
puts "executing MyClass.delegate()"
end
delegate
end
That same structure can be replicated like this:
class Dog
def bark
puts “woof”
end
bark
end
which will produce the same type of error:
1.rb:7:in `<class:Dog>': undefined local variable or method `bark' for Dog:Class (NameError)
from 1.rb:1:in `<main>'
When you call a method and you don't specify a receiver, ruby uses whatever object is currently assigned to the self variable as the receiver.
Inside a method, ruby assigns the object that called the method to the self variable. The object that called the method is not the same thing as the class (object) in which the method is defined.
Inside a class, but outside of any method definitions, ruby assigns the class (object) to self.
Note that it is the instances of the Dog class that can call the def's inside the Dog class, e.g. bark(). Similarly, it is the instances of the singleton class that can call the def's inside the singleton class, e.g. delegate()--the singleton class itself cannot call the def's inside the singleton class. The whole reason they are called singleton classes is because singleton classes have only one instance--in your case the one instance of the singleton class is MyClass. As a result, MyClass can call delegate(), but the singleton class cannot call delegate().
I don't understand really what a class method on an eignclass is
however.
Personally, I don't use the term eigenclass
. In my opinion, ruby has made a decision that the term is singleton class
. If you look through the docs for the Object class, there are no method names that have eigenclass
in them, yet there are method names with singleton class
in them.
All objects have a singleton class. A singleton class is an object. Therefore, every singleton class also has a singleton class--which means that the chain of singleton classes is infinite:
class Dog
end
s1 = Dog.singleton_class
puts s1
s2 = s1.singleton_class
puts s2
s3 = s2.singleton_class
puts s3
--output:--
#<Class:Dog>
#<Class:#<Class:Dog>>
#<Class:#<Class:#<Class:Dog>>>
Which means you can do stuff like this:
class Dog
class <<self #s1
class <<self #s2
def greet #Instances of s2 can call greet, and the only instance of s2 is s1.
puts "hello"
end
end
end
end
class Dog
class <<self
#Inside here self = Dog's singleton class = s1
greet #equivalent to Dogs_singleton_class.greet
end
end
--output:--
hello
However, I've never seen anyone use a singleton class of a singleton class (s2) before in their code. I did it once to answer a question a long, long time ago, and nobody had any idea what I was talking about.
There are some method lookup diagrams here, which might prove useful.
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.
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.
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.
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.
Related Topics
Bundler Install Getting "I18N Requires Ruby Version >= 1.9.3"
Open_Id_Authentication - "Openidauthentication.Store Is Nil. Using In-Memory Store." Problem
Convert String to Symbol-Able in Ruby
How to Build a Ruby Hash Out of Two Equally-Sized Arrays
Parse Command Line Arguments in a Ruby Script
Cannot Access Local Sinatra Server from Another Computer on Same Network
How Much Performance Do You Get Out a Heroku Dynos/Workers
Finding Nil Has_One Associations in Where Query
Are There Any Ipython-Like Shells for Ruby or Rails
What Is the Use of "#!/Usr/Local/Bin/Ruby -W" at the Start of a Ruby Program
How to Get Constants Defined by Ruby's Module Class via Reflection
How to Create a Ruby Date Object from a String
Ruby: Finding Most Recently Modified File
How to Convert a Comma-Separated String into an Array
Undefined Method 'Devise' for User
How Many Rails Apps on 1 Heroku Dyno
Imagemagick 7 with Rmagick 2.16 on MACos Sierra Can't Find Magickwand.H