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

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.
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.