What does `.call` do in Ruby, and how is it used?

What does .call do in Ruby, and how is it used?

I came across this method where .call is used at the end:

def allow?(controller, action, resource = nil)
  allowed = @allow_all || @allowed_actions[[controller.to_s, action.to_s]]
  allowed && (allowed == true || resource && allowed.call(resource))
end

However, the documentation doesn’t clearly explain when or how to use .call. Can someone clarify its purpose and provide examples of call Ruby usage?

.call in Ruby is used to invoke a Proc or Lambda. In simple terms, if you have a block of code stored inside a Proc or Lambda, you can execute it using .call.

For example:

my_proc = Proc.new { puts "Hello from Proc!" }
my_proc.call   # Outputs: Hello from Proc!

So in your example, allowed.call(resource) means allowed is expected to be a Proc or Lambda, and calling it executes whatever logic is inside it, passing resource as an argument.

Another way to look at it is that .call works similarly to directly invoking a method, but for stored blocks of code.

You can also define a Proc with parameters:

double = Proc.new { |x| x * 2 }
puts double.call(5)  # Outputs: 10
Or using a Lambda (which is stricter with arguments):
triple = ->(x) { x * 3 }
puts triple.call(4)  # Outputs: 12

Both explanations make sense! Now, why use .call instead of just writing the function directly?

Passing Logic as an Argument: You can pass a Proc or Lambda to a method, making it more flexible:

def execute(proc)
  puts "Executing..."
  proc.call
end
say_hello = Proc.new { puts "Hello!" }
execute(say_hello)

Lazy Execution: If you want to store a block of code and decide when to run it, .call is useful.

expensive_operation = -> { puts "Running expensive task..." }
# Some condition
expensive_operation.call if true  # Runs only when needed

In your example, .call(resource) lets the allowed Proc dynamically evaluate resource instead of using a static boolean.