Blocks

Ruby is a dynamic, beginner-friendly programming language, and blocks — chunks of code you hand to a method — are the feature that makes Ruby feel uniquely expressive.

Learn Blocks in our free Ruby course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Ruby course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

By the end of this lesson you'll pass blocks with do...end and {' '} , and write your own methods that run them with yield .

What You'll Learn in This Lesson

1️⃣ Passing Blocks to Methods

Many built-in methods accept a block. You write the block right after the call, using do...end for several lines or {' '} for one. The method feeds values to your block through parameters named between |pipes| .

2️⃣ Writing Methods that Take Blocks (yield)

Your own methods can accept blocks too. Call yield to run the block — as often as you like — and pass arguments with yield(value) . To make a block optional, check block_given? first so you never yield into thin air.

Your turn. A repeat method is sketched for you — it yields the current count. Run it as-is, then customise the block message.

Write a method that prints a line before and after running a block. This "do something around a block" pattern appears all over Ruby (think File.open ). Run with ruby banner.rb .

📋 Quick Reference — Blocks

Practice quiz

What does yield do inside a method?

  • Returns from the method immediately
  • Runs the block that was passed to the method
  • Pauses execution for one second
  • Defines a new block

Answer: Runs the block that was passed to the method. yield invokes the block attached to the current method call.

Which two syntaxes can you use to write a block?

Blocks use do...end (usually multi-line) or curly braces { } (usually one-line).

By convention, when do you use { } instead of do...end?

  • For short, single-line blocks
  • Only inside classes
  • When the block takes no parameters
  • For multi-line blocks

Answer: For short, single-line blocks. Convention reserves { } for short one-liners and do...end for multi-line blocks.

What does block_given? return?

  • The block's return value
  • true only when a block was passed to the current method
  • The number of block parameters
  • Always true inside a method

Answer: true only when a block was passed to the current method. block_given? is true exactly when a block was attached to the call, so you can yield safely.

Calling yield when no block was passed raises which error?

  • NoMethodError
  • ArgumentError
  • LocalJumpError
  • FrozenError

Answer: LocalJumpError. yield with no block raises LocalJumpError; guard with block_given? to avoid it.

Where do block parameters go?

  • In parentheses after the method name
  • Between vertical bars (pipes), like |n|
  • Inside square brackets
  • After the keyword yield only

Answer: Between vertical bars (pipes), like |n|. Block parameters are named between pipes: { |n| n * 2 } or do |item, i| ... end.

Given def twice; yield; yield; end, how many times does the block run?

  • Zero
  • Once
  • Twice
  • It raises an error

Answer: Twice. Each yield runs the block once, so two yields run it twice.

each_with_index yields how many values to its block?

  • One (the element)
  • Two (the element and its index)
  • Three
  • Zero

Answer: Two (the element and its index). each_with_index yields the element and its position, so name two parameters |item, i|.

With def with_tax(p); yield(p * 1.2); end, what does with_tax(100) { |t| puts t } print?

  • 100
  • 120.0
  • 20.0
  • 1.2

Answer: 120.0. yield passes 100 * 1.2 = 120.0 into the block, which prints it.

How many times does [1, 2, 3].each { |n| puts n } run the block?

  • Once
  • Twice
  • Three times
  • Zero times

Answer: Three times. each runs the block once per element — three times for a three-element array.