Methods & Blocks
Methods
Methods in Ruby are set of expressions that 1) always return a value, 2) are always associated with some Ruby object.
Ruby methods are not straightforward objects but can be obtained as objects using an Object.method
method. Such a method object might be 1) called, 2) used as a block or 3) unbound from its associated object and bound to another.
class Mathematician
def sum(a, b)
a + b
end
end
engineer = Mathematician.new
engineer.sum(2, 2) # => 4
engineer.sum.class # => ArgumentError: wrong number of arguments (given 0, expected 2)
object_method = engineer.method(:sum)
object_method.class # => Method
object_method.call(3, 3) # => 6
Method Arguments
Arguments can be provided to Ruby methods through: 1) standard arguments, 2) keyword arguments, and 3) variable length arguments.
# Standard arguments:
def sum(first_number, second_number)
first_number + second_number
end
sum(2, 2) #=> 4
sum(2) #=> ArgumentError: wrong number of arguments (given 1, expected 2)
# Keyword arguments:
def sum(first_number:, second_number:)
first_number + second_number
end
sum(first_number: 2, second_number: 2) # => 4
sum(second_number: 2, first_number: 2) # => 4
sum(first_number: 2) # => missing keyword: second_number
# Variable length arguments:
def sum_all(*args)
args.inject(0, :+)
end
sum_all(1, 2, 3) # => 6
sum_all(1, 2, 3, 4, 5) # => 15
With both - standard arguments and keyword arguments - it is possible to use default values making the arguments with default values optional.
def sum(first_number, second_number = 2)
first_number + second_number
end
sum(2, 3) #=> 5
sum(2) #=> 4
def sum(first_number:, second_number: 2)
first_number + second_number
end
sum(first_number: 2, second_number: 3) # => 5
sum(first_number: 2) # => 4
Blocks
It might be said that an inspiration for blocks were higher-order functions.
Blocks in Ruby are set of expressions accepting arguments that 1) do not return a value by itself, 2) are not associated with any Ruby object. Blocks are not objects but can be turned to objects with &
notation signalled in a given method's arguments.
Blocks are signalled by the do ... end
notation or the { ... }
notation and their arguments are enclosed in |...|
notation.
Blocks can be 1) called from within a method or 2) yielded to.
Calling Blocks
Blocks can be turned into objects (namely procs) and called when its underlying method uses &
in its arguments.
def sum(&my_block)
my_block.call(2, 2)
end
sum { |a, b| a + b } # => 4
sum { |a, b| a - b } # => 0
sum { |a, b| a + a + b + b } # => 8
Yielding to Blocks
The same results as with calling blocks can be achieved with yielding to blocks with a yield
keyword.
def sum
yield(3, 4)
end
sum { |a, b| a + b } # => 7
sum { |a, b| a - b } # => -1
sum { |a, b| a + a + b + b } # => 14