6

I don't know any Ruby and am reading some documentationon it now. A doubt I have just after reading about using code blocks and the "yield" keyword is whether it is possible to pass more than one code block to a function, and use both at will from within the called function.

4 Answers 4

9

You can pass only one block at once but blocks are actually Proc instances and you can pass as many instances you wish as parameters.

def mymethod(proc1, proc2, &block)
  proc1.call
  yield if block_given?
  proc2.call
end

mymethod(Proc.new {}, Proc.new {}) do
  # ...
end

However, it rarely makes sense.

Sign up to request clarification or add additional context in comments.

4 Comments

Blocks aren't exactly procs. They have common usecases and syntaxes, but they have enough implementation differences to cause confusing behavior. It's a bit pedantic, but the scoping difference has bit me before.
@fengb I just made a test. gist.github.com/242746 Do you have some more documentation about the difference between Proc and block? Ruby is telling me a block is a Proc.
Blocks are implicitly "typecasted" to proc by using the &var syntax. But there are certain operations that behave differently when used as a block versus a proc. Long winded but comprehensive comparison: innig.net/software/ruby/closures-in-ruby.rb
Thanks. This is a long article, I'm going to crunch it in small pieces. :)
1

Syntactically, using the yield statement only supports one code block that's passed to the function.

Of course, you can pass a function multiple other functions or "code block objects" (Proc objects), and use them, but not by simply using yield.

Comments

1

You can create Proc objects and pass around as many as you like.

I recommend reading this page to understand the subtleties of all different block- and closure-like constructs Ruby has.

Comments

1

You can use the call method rather than yield to handle two separate blocks passed in.

Here's how:

def mood(state, happy, sad )
  if (state== :happy)
    happy.call
  else
    sad.call
  end
end

mood(:happy, Proc.new {puts 'yay!'} , Proc.new {puts 'boo!'})
mood(:sad, Proc.new {puts 'yay!'} , Proc.new {puts 'boo!'})

You can pass args with for example:

happy.call('very much')

arguments work just like you'd expect in blocks:

Proc.new {|amount| puts "yay #{amount} !"}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.