Methods are great for DRYing up your code and organizing logic in a single place. They act a little bit like a black box. Here are some tidbits that might not be so obvious with Ruby methods.
All methods have to be called on an object
In Ruby, there has to be an object that receives a method call, even if you don’t see it. For example, the “puts” method or the multiplication operator:
puts "Hello" puts self puts self.class p self.class.ancestors # Hello # main # Object # [Object, Kernel, BasicObject] puts 8.class p 8.class.ancestors # Integer # [Integer, Numeric, Comparable, Object, Kernel, BasicObject] # * is actually a method with the 2 being passed in as the parameter puts 8.*(2) puts 8 * 2 # 16 # 16
So in words:
- “puts” is a method
- This method is called on an object.
- That object is stored in the self variable.
- That variable points to the object which is named main (Akin to how a string variable points to a an object named String).
Obviously you won’t be able to call “self.puts” because Ruby doesn’t allow explicit receivers for private methods. I won’t get into the details of self but just know that its value could change depending on where you are in your program and is the default receiver for method calls.
Fun fact: Within a method, Ruby will check whether something is a local variable first. If not, it looks for an implicit receiver next.
So we call methods on objects and sometimes we’ll pass a block and/or a method parameter. It’s good to keep in mind Ruby passes variables by reference. For instance:
def say_something(words) words = "z" end my_word = "hello" say_something(my_word) # The method call actually altered the value puts my_word # helloz
def add_headphone(brand, model, version=1.0) puts brand puts model puts version end add_headphone("HiFiMan", "HE-1000") add_headphone("HiFiMan", "HE-1000", 2.0)