There are many different kinds of methods in ruby, including module methods, class methods, instance methods, and singleton methods.
module Animal
def self.browse_petco # module method
p "browsing petco"
end
end
class Dog
include Animal
def self.adopt_a_dog # class method
p "adopting a dog"
end
def bark # instance method
p "barking"
end
end
Animal.browse_petco # => "browsing petco"
Dog.adopt_a_dog # => "adopting a dog"
spot = Dog.new
spot.bark # => "barking"
def spot.roll_over # singleton method
p "rolling over"
end
spot.roll_over # => "rolling over"
Class methods are called on classes and are defined with a self.
or <ClassName>.
Examples include .new
, to create an instance of a class, and rails model methods like .find
, .find_by
, .all
, and .where
.
Module methods are like class methods but for modules.
Instance methods are called on instances of classes. Examples include getters and setters. When referencing instance methods within a class, it's sometimes necessary to use the self.
keyword. For example, consider:
class Person
attr_accessor :age
def initialize(opts)
@age = opts[:age]
end
def grow_older
p age # => 45
age = age + 10 # => undefined method `+' for nil:NilClass (NoMethodError)
end
end
sandra = Person.new(age: 45)
sandra.grow_older
Within the grow_older
instance method, we test the age
getter by printing age; it works. We then use that that same method on the next line (age + 10
) and get an error. Using self.
, we can make the error go away, but the setter than still does not work:
class Person
attr_accessor :age
def initialize(opts)
@age = opts[:age]
end
def grow_older
age = self.age + 10
end
end
sandra = Person.new(age: 45)
sandra.grow_older
p sandra # => #<Person:0x00007fd5ea13c2d0 @age=45>
Note that when sandra
is printed out, her age remains 45. This is because age =
is an allowed operation (assigning a value to a variable) and does not indicate to ruby that it needs to look for an instance method. self.
eliminates the ambiguity:
class Person
attr_accessor :age
def initialize(opts)
@age = opts[:age]
end
def grow_older
self.age = self.age + 10
end
end
sandra = Person.new(age: 45)
sandra.grow_older
p sandra # => #<Person:0x00007fd5ea13c2d0 @age=55>
These are methods that are defined for a specific instance. They are the least common of the four.