A Ruby method can call yield to run a block supplied by the caller.

yield `yield` transfers control from a method to the block passed with the method call.

Blocks Yield

name
blocks_yield.rb
Replay: real traced execution (multi-file project)
def with_greeting(name)
  puts "before block"
  yield(name)
  puts "after block"
end

name = "Ruby"

with_greeting(name) do |value|
  puts "hello #{value}"
end
def with_greeting(name)
  puts "before block"
  yield(name)
  puts "after block"
end

name = "Ada"

with_greeting(name) do |value|
  puts "hello #{value}"
end
def with_greeting(name)
  puts "before block"
  yield(name)
  puts "after block"
end

name = "Matz"

with_greeting(name) do |value|
  puts "hello #{value}"
end
  1. name ← Ruby

    7name→ Ruby = "Ruby"  #@name="Ada", "Matz"89with_greeting(nameRuby) do |value|10  puts "hello #{value}"11end
  2. def with_greeting(name)

    1def with_greeting(nameRuby)2  puts "before block"3  yield(nameRuby)4  puts "after block"
    outputbefore block
  3. do |value|

    2  puts "before block"3  yield(nameRuby)4  puts "after block"5end67name = "Ruby"  #@name="Ada", "Matz"89with_greeting(nameRuby) do |valueRuby|10  puts "hello #{valueRuby}"11end
    outputhello Ruby
    after block
  1. name ← Ada

    7name→ Ada = "Ada"89with_greeting(nameAda) do |value|10  puts "hello #{value}"11end
  2. def with_greeting(name)

    1def with_greeting(nameAda)2  puts "before block"3  yield(nameAda)4  puts "after block"
    outputbefore block
  3. do |value|

    2  puts "before block"3  yield(nameAda)4  puts "after block"5end67name = "Ada"89with_greeting(nameAda) do |valueAda|10  puts "hello #{valueAda}"11end
    outputhello Ada
    after block
  1. name ← Matz

    7name→ Matz = "Matz"89with_greeting(nameMatz) do |value|10  puts "hello #{value}"11end
  2. def with_greeting(name)

    1def with_greeting(nameMatz)2  puts "before block"3  yield(nameMatz)4  puts "after block"
    outputbefore block
  3. do |value|

    2  puts "before block"3  yield(nameMatz)4  puts "after block"5end67name = "Matz"89with_greeting(nameMatz) do |valueMatz|10  puts "hello #{valueMatz}"11end
    outputhello Matz
    after block

Follow the Block

  1. name starts as Ruby.
  2. with_greeting prints before block.
  3. The method yields Ruby to the block.
  4. The block prints hello Ruby.
  5. Control returns to the method, which prints after block. | moment | output | | --- | --- | | before yield | before block | | inside block | hello Ruby | | after block returns | after block |

Exercise: blocks_yield.rb

Reproduce the three default output lines, then use the pinned name variants to predict hello Ada and hello Matz.