Ruby Tuesday – Proc#call

Today’s Ruby Tuesday is Proc#call.

Procs are blocks of code that are bound to local variables, and as such, we need a way to be able to invoke them at a later time. Enter Proc#call.

Proc#call takes a list of arguments which are then used as the arguments to the Proc that call is being invoked on.

Proc.new {|x| x * x }.call 9
# => 81
Kernel.proc{|x| x * x }.call 11
# => 121
lambda {|x| x * x }.call 7
# => 49
->(x){x * x}.call 5
# => 25
->(x){x * x}.call 5
# => 25

If Proc#call is invoked with extra arguments, it will either discard the extra arguments, or raise an error if it was created as a lambda.

Proc.new {|x| x * x }.call 9, 3
# => 81
Kernel.proc{|x| x * x }.call 11, 15
# => 121
lambda {|x| x * x }.call 7, 13
# ArgumentError: wrong number of arguments (2 for 1)
# from (pry):94:in `block in __pry__'
->(x){x * x}.call 5, 3
# ArgumentError: wrong number of arguments (2 for 1)
# from (pry):93:in `block in __pry__'

Proc#call also has some other syntactic sugar providing alias for calling the method. You can use [], .(), or even the method Proc#yield as variations of Proc#call.

Proc.new {|x| x * x }[9]
=> 81
Proc.new {|x| x * x }.(9)
=> 81
Proc.new {|x| x * x }.yield 9
=> 81

As an extra bonus, there is also the method Method#call that can be used when you have an named method and you have a Method object for it. This call method behaves in the manner of lambda in that it expects the correct number of arguments to be passed to it.

def square(x)
  x * x
end

method(:square).call 2
# => 4
method(:square).call 2, 4
# ArgumentError: wrong number of arguments (2 for 1)
# from (pry):78:in `square'

–Proctor