To use self. or not.. in Rails

I've been coding in Ruby for sometime now, but I don't understand when to use:

def self.METHOD_NAME
end

or just:

def METHOD_NAME
end

In any Rails model. Is "self" a modifier like private in Java? When should I use it and when not?. Thanks a ton.


Solution 1:

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.

Solution 2:

A quick explanation of what that means:

In ruby, you can define methods on a particular object:

a = "hello"

def a.informal
  "hi"
end

a.informal
=> "hi"

What happens when you do that is that the object a, which is of class String, gets its class changed to a "ghost" class, aka metaclass, singleton class or eigenclass. That new class superclass is String.

Also, inside class definitions, self is set to the class being defined, so

class Greeting
  def self.say_hello
    "Hello"
  end
  #is the same as:
  def Greeting.informal
    "hi"
  end
end

What happens there is that the object Greeting, which is of class Class, gets a new metaclass with the new methods, so when you call

Greeting.informal
=> "hi"

There's no such thing as class methods in ruby, but the semantics are similar.

Solution 3:

A good guide on when to use which one:

  • If the method depends on any internal state of the object, or must know which instance of the object it is addressing, then DO NOT make it a class (self.) method.
  • If the method does not depend on the state of the object, or on having a specific instance of the object, then in may be made a class method.

When making a class method, think carefully about which class or module it belongs in. If you ever catch yourself duplicating code in class methods across classes, factor it into a module that other classes may mix in.

Solution 4:

In this context - def self.method_name makes it sort of equivalent to the Java static method:

ruby:

class HexHelper
  def self.to_h(num)
    sprintf("%x", num)
  end
end

use: HexHelper.to_h(12345)

java:

public class HexHelper
{
  public static String toHex(int num)
  {
    return new PrintfFormat("%x").sprintf(num);
  }
}

use: HexHelper.toHex(12345)

Solution 5:

self is always the current object

When you see self here

def self.method_name end

You are not in an instance method, so self is the current Class object.