Passing optional blocks - is there a better solution?

Here again, I do have a solution, but I would like to get an opinion, on
whether there is a better one.

I have a function f(a,b) which allows an optional block:

f(3,4)
f(3,4) { |x| … }

are both acceptable calls. Then I have a function g(b), which behaves
like f, but supplies to f zero for the first argument (it’s kind of
“currying on the first parameter”). This means that g(5) is equivalent
to f(0,5), and

g(5) {…}

is equivalent to

f(0,5) { … }

I implemented it like this (example):

def f(a,b,&block)
r=a+b
if(block_given?)
block.call®
else
puts r
end
end

def g(b,&block)
f(0,b,&block)
end

Is this a good solution, or can it be done better? I’ve read that it is
advisable to use a Proc.call object, but I don’t see how I can use it in
my case, since the block is always optional.

Is this a good solution, or can it be done better?

def f a, b
r = a + b
yield(r) if block_given?
puts r
end

Here you’ll find more references and info:

Vlad M_ wrote in post #1151585:

Is this a good solution, or can it be done better?

def f a, b
r = a + b
yield® if block_given?
puts r
end

You are right in that this spares us from using an explicit block
argument on f, but what about g? I don’t see a way to omit the &block
argument in g.

In my concrete application, I have several functions calling each other,
each one accepting an optional block, which, if present, gets passed on
the next function. The innermost is the one which actually ylelds the
block. I see that I don’t need a &block argument on the innermost
function, but is there a clever way to avoid it in the other ones as
well?

Vlad M_ wrote in post #1151588:

is there a clever way to avoid it in the other ones as
well?

I don’t see any. You need the block reference to pass it to other
methods.

I feared so. Thank you for confirming this.

is there a clever way to avoid it in the other ones as
well?

I don’t see any. You need the block reference to pass it to other
methods.