Forum: Ruby Passing optional blocks - is there a better solution?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
on 2014-07-02 15:30
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(r)
  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.
7e1614e9431deef2bf123693dd6bb59d?d=identicon&s=25 Vlad M_ (vladm)
on 2014-07-04 09:53
> 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:
http://stackoverflow.com/questions/1410160/ruby-pr...
0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
on 2014-07-04 10:14
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(r) 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?
7e1614e9431deef2bf123693dd6bb59d?d=identicon&s=25 Vlad M_ (vladm)
on 2014-07-04 10:43
> 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.
0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
on 2014-07-04 11:01
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.
This topic is locked and can not be replied to.