More natural way of Proc calling in Ruby 1.9
Question
As we know, there are several way of Proc calling in Ruby 1.9
f =->n {[:hello, n]}
p f[:ruby] # => [:hello, :ruby]
p f.call(:ruby) # => [:hello, :ruby]
p f.(:ruby) # => [:hello, :ruby]
p f === :ruby # => [:hello, :ruby]
I am curious, what is more 'natural' way of calling Proc? 'Natural', probably, means more Computer Science - like way.
Solution
The second option is by far the most used.
p f.call(:ruby) # => [:hello, :ruby]
It makes it more similar to a standard method. Also, some libraries actually rely on duck typing when validating arguments checking the availability of the #call
method. In this case, using #call
ensures you can provide a lambda or any other object (including a Class) that responds to #call
.
Rack
middlewares are a great example of this convention. The basic middleware can be a lambda, or you can supply more complex logic by using classes.
OTHER TIPS
I always use option 3. Considering the syntactic ambiguities of being able to call methods without parentheses, this is the closest you can get to actual method call syntax.
I saw the first way used in Rack source code. It confused me in a long time. It's picked from lib/rack/builder.rb (version: 1.6.0.alpha)
module Rack
class Builder
...
def to_app
app = @map ? generate_map(@run, @map) : @run
fail "missing run or map statement" unless app
# This is the first option calling a proc
# @use is a array of procs (rack middleware)
@use.reverse.inject(app) { |a,e| e[a] }
end
...
end
end