Question

How can I yield two diferent blocks in the same method

the example code:

def by_two(n,a)
    yield n
    yield a
end

proc1 = proc {|x| p x * 2}
proc2 = proc {|x| x + 100}

by_two(10, 300, &proc1, &proc2)

the error is such -

main.rb:7: syntax error, unexpected ',', expecting ')'
by_two(10, 300, &proc1, &proc2)

Any suggestions where and what is wrong? Thanks

Was it helpful?

Solution

Blocks are a lightweight way of passing a single anonymous procedure to a method. So, by definition, there cannot be two blocks passed to a method. It's not just semantically impossible, it isn't even possible syntactically.

Ruby does support first-class procedures in the form of Procs, however, and since those are just objects like any other object, you can pass as many of them as you want:

def by_two(n, a, proc1, proc2)
  proc1.(n)
  proc2.(a)
end

proc1 = proc {|x| p x * 2}
proc2 = proc {|x| x + 100}

by_two(10, 300, proc1, proc2)
# 20
# => 400

Since the introduction of lambda literals in Ruby 1.9, Procs are almost as syntactically lightweight as blocks, so there is not a big difference anymore:

by_two(10, 300, -> x { p x * 2 }, -> x { x + 100 })
# 20
# => 400

OTHER TIPS

You cannot yield two blocks in a method.

But you can take two procs.

def by_two(n, a, pr1, pr2)
  pr1.call(n)
  pr2.call(a)
end
by_two(10, 300, proc1, proc2)

The answer to your question is: You cannot do it if you insist on blocks! Ruby does not support multiple blocks per method. A way to go around this is to pass two procs as variables like this:

def by_two(n,a, proc1=nil, proc2=nil)
  if proc1 || proc2
    proc1.yield n if proc1
    puts proc2.yield a if proc2
  else
    puts "no procs"
  end
end

proc1 = proc {|x| p x * 2}
proc2 = proc {|x| x + 100}
by_two(10, 300, proc1, proc2)

by_two(10, 300, proc1)

by_two(10, 300)

Output:

20
400
20
no procs

Another possibility is this:

NO_OP = proc {}

def by_two(n,a, proc1=NO_OP, proc2=NO_OP)
  if proc1 == NO_OP && proc2 == NO_OP
    puts "no procs"
  else
    proc1.yield n
    proc2.yield a
  end
end

proc1 = proc {|x| p x * 2}
proc2 = proc {|x| p x + 100}
by_two(10, 300, proc1, proc2)

by_two(10, 300, proc1)

by_two(10, 300)

It has the same output.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top