Reputation: 5948
Is it possible (if yes how) to pass a block as a keyword argument in a ruby method?
Basically, I'd like to do
pippo(even: {|n| n+1 }, odd: {|n| n-1})
Having the method defined as such
def pippo(even: , odd:)
even? ? even.yield(self) : odd.yield(self)
end
Thanks
Upvotes: 3
Views: 1529
Reputation: 369458
No, this is not possible. Blocks aren't objects, you can't pass them as arguments, except as block arguments. They are a lightweight syntactic and semantic construct that is only allowed as a block argument to a message send. The light weight of blocks is predicated on the fact that there can be at most one block, and thus it doesn't need to be named and/or bound to a parameter.
What you can do, however, is pass multiple Proc
s or lambdas. After all, Proc
s and lambdas are objects like any other object, so you can pass them as arguments like any other object:
pippo(even: -> n { n+1 }, odd: -> n { n-1 })
def pippo(even: , odd:)
if even? then even.(self) else odd.(self) end
end
Actually, this allows you to pass any object which responds to call
, e.g. a Method
:
pippo(even: 1.method(:+), odd: 1.method(:-))
Upvotes: 5
Reputation: 211590
If you want to supply multiple blocks you need to pass them through as a Proc, or use the lambda
construct to declare them:
when(
even: -> (x) { x+1 },
odd: -> (x) { x-1 }
)
You can also declare them using proc { ... }
or lambda { ... }
which is the old style declaration for same.
Upvotes: 4