my.code(); Logomy.code();
Ruby-5.ブロックとイテレータ

my.code(); Logomy.code();

  • C++
    • 0.C++の世界へようこそ
    • 1.型システムと制御構造
    • 2.データ集合とモダンな操作
    • 3.ポインタとメモリ管理
    • 4.関数と参照渡し
    • 5.プロジェクトの分割とビルド
    • 6.クラスの基礎
    • 7.クラスを使いこなす
    • 8.継承とポリモーフィズム
    • 9.テンプレート
    • 10.STL ①:コンテナ
    • 11.STL ②:アルゴリズムとラムダ式
    • 12.RAIIとスマートポインタ
  • JavaScript
    • 0.JavaScriptへようこそ
    • 1.基本構文とデータ型
    • 2.制御構文
    • 3.関数とクロージャ
    • 4.'this'の正体
    • 5.オブジェクトとプロトタイプ
    • 6.クラス構文
    • 7.配列とイテレーション
    • 8.非同期処理①: Promise
    • 9.非同期処理②: Async/Await
  • Python
    • 0.環境構築と基本思想
    • 1.基本構文とデータ型
    • 2.リスト、タプル、辞書、セット
    • 3.制御構文と関数
    • 4.モジュールとパッケージ
    • 5.オブジェクト指向プログラミング
    • 6.ファイルの入出力とコンテキストマネージャ
    • 7.例外処理
    • 8.ジェネレータとデコレータ
  • Ruby
    • 0.rubyの世界へようこそ
    • 1.基本構文とデータ型
    • 2.制御構造とメソッド定義
    • 3.すべてがオブジェクト
    • 4.コレクション (Array, Hash, Range)
    • 5.ブロックとイテレータ
    • 6.クラスとオブジェクト
    • 7.モジュールとMix-in
    • 8.Proc, Lambda, クロージャ
    • 9.標準ライブラリの活用
    • 10.テスト文化入門
    • 11.メタプログラミング入門
  • Rust
    • 0.Rustの世界へようこそ
    • 1.基本構文と「不変性」
    • 2.関数と制御フロー
    • 3.所有権
    • 4.借用とスライス
    • 5.構造体とメソッド構文
    • 6.列挙型とパターンマッチ
    • 7.モジュールシステムとパッケージ管理
    • 8.コレクションと文字列
    • 9.エラーハンドリング
    • 10.ジェネリクスとトレイト
    • 11.ライフタイム
  • TypeScript
    • 0.TypeScriptへようこそ
    • 1.基本的な型と型推論
    • 2.オブジェクト、インターフェース、型エイリアス
    • 3.関数の型定義
    • 4.型を組み合わせる
    • 5.ジェネリクス
    • 6.クラスとアクセス修飾子
    • 7.非同期処理とユーティリティ型
my.code(); Logomy.code();

環境構築不要、その場で実践。

ut-code / my-code

Copyright © 2026 ut.code();

ut.code(); について
公式ウェブサイト公式 𝕏 アカウント

第5章: ブロックとイテレータ - Rubyの最重要機能

Rubyの学習において、ブロック (Block) は最も重要で強力な機能の一つです。他言語の経験者にとって、これはラムダ式や無名関数、クロージャに似た概念ですが、Rubyではこれが言語構文の核に深く組み込まれています。

この章では、ブロックの使い方と、ブロックを活用する「イテレータ」と呼ばれるメソッドを学びます。

ブロック構文: do...end と {}

ブロックとは、メソッド呼び出しに渡すことができるコードの塊です。メソッド側は、受け取ったそのコードの塊を好きなタイミングで実行できます。

ブロックには2種類の書き方があります。

  1. { ... } (波括弧): 通常、1行で完結する場合に使われます。
  2. do ... end: 複数行にわたる処理を書く場合に使われます。

どちらも機能的にはほぼ同じです。最も簡単な例は、指定した回数だけブロックを実行する times メソッドです。

Ruby 実行環境
ブラウザ上で動作するRuby3.4のREPL実行環境です。
プロンプト (irb>) の後にコマンドを入力し、Enterキーで実行します。
Ctrl+Cまたは左上の停止ボタンで実行中のコマンドを中断できます。
irb(main):001:0> 3.times { puts "Hello!" }
Hello!
Hello!
Hello!
=> 3

irb(main):002:0> 3.times do
irb(main):003:1* puts "Ruby is fun!"
irb(main):004:1> end
Ruby is fun!
Ruby is fun!
Ruby is fun!
=> 3

3.times というメソッド呼び出しの後ろに { ... } や do ... end で囲まれたコードブロックを渡しています。times メソッドは、そのブロックを3回実行します。

ブロック引数

ブロックは | ... | を使って引数を受け取ることができます。

Ruby 実行環境
ブラウザ上で動作するRuby3.4のREPL実行環境です。
プロンプト (irb>) の後にコマンドを入力し、Enterキーで実行します。
Ctrl+Cまたは左上の停止ボタンで実行中のコマンドを中断できます。
irb(main):018:0> ["Alice", "Bob"].each do |name|
irb(main):019:1* puts "Hello, #{name}!"
irb(main):020:1> end
Hello, Alice!
Hello, Bob!
=> ["Alice", "Bob"]

ブロックの戻り値

(Rubyのすべての式と同様に)ブロックも戻り値を持ちます。ブロックの戻り値とは、ブロック内で最後に評価された式の値です。

Ruby 実行環境
ブラウザ上で動作するRuby3.4のREPL実行環境です。
プロンプト (irb>) の後にコマンドを入力し、Enterキーで実行します。
Ctrl+Cまたは左上の停止ボタンで実行中のコマンドを中断できます。
irb(main):021:0> result = [1, 2].map do |n|
irb(main):022:1* m = n * 10       # mは 10, 20
irb(main):023:1* m + 5            # ブロックの戻り値 (15, 25)
irb(main):024:1> end
=> [15, 25]

代表的なイテレータ

Rubyでは、コレクション(配列やハッシュなど)の各要素に対して処理を行うメソッドをイテレータ (Iterator) と呼びます。イテレータは通常、ブロックを受け取って動作します。

代表的なイテレータを見ていきましょう。

each

each は、コレクションの各要素を順番に取り出してブロックを実行します。他言語の foreach ループに最も近いものです。

|n| の部分はブロック引数と呼ばれ、イテレータが取り出した要素(この場合は配列の各要素)を受け取ります。

Ruby 実行環境
ブラウザ上で動作するRuby3.4のREPL実行環境です。
プロンプト (irb>) の後にコマンドを入力し、Enterキーで実行します。
Ctrl+Cまたは左上の停止ボタンで実行中のコマンドを中断できます。
irb(main):001:0> numbers = [1, 2, 3]
=> [1, 2, 3]

irb(main):002:0> numbers.each do |n|
irb(main):003:1* puts "Current number is #{n}"
irb(main):004:1> end
Current number is 1
Current number is 2
Current number is 3
=> [1, 2, 3]

Note: each メソッドの戻り値は、元の配列 ([1, 2, 3]) 自身です。each はあくまで「繰り返すこと」が目的であり、ブロックの実行結果は利用しません。

map (collect)

map は、各要素に対してブロックを実行し、そのブロックの戻り値を集めた新しい配列を返します。

Ruby 実行環境
ブラウザ上で動作するRuby3.4のREPL実行環境です。
プロンプト (irb>) の後にコマンドを入力し、Enterキーで実行します。
Ctrl+Cまたは左上の停止ボタンで実行中のコマンドを中断できます。
irb(main):005:0> numbers = [1, 2, 3]
=> [1, 2, 3]

irb(main):006:0> doubled = numbers.map { |n| n * 2 }
=> [2, 4, 6]

irb(main):007:0> puts doubled.inspect
[2, 4, 6]
=> nil

irb(main):008:0> puts numbers.inspect # 元の配列は変更されない
[1, 2, 3]
=> nil

map は、元の配列を変換した新しい配列が欲しい場合に非常に便利です。

select (filter)

select は、各要素に対してブロックを実行し、ブロックの戻り値が真 (true) になった要素だけを集めた新しい配列を返します。

Ruby 実行環境
ブラウザ上で動作するRuby3.4のREPL実行環境です。
プロンプト (irb>) の後にコマンドを入力し、Enterキーで実行します。
Ctrl+Cまたは左上の停止ボタンで実行中のコマンドを中断できます。
irb(main):009:0> numbers = [1, 2, 3, 4, 5, 6]
=> [1, 2, 3, 4, 5, 6]

irb(main):010:0> evens = numbers.select { |n| n.even? } # n.even? は n % 2 == 0 と同じ
=> [2, 4, 6]

find (detect)

find は、ブロックの戻り値が真 (true) になった最初の要素を返します。見つからなければ nil を返します。

Ruby 実行環境
ブラウザ上で動作するRuby3.4のREPL実行環境です。
プロンプト (irb>) の後にコマンドを入力し、Enterキーで実行します。
Ctrl+Cまたは左上の停止ボタンで実行中のコマンドを中断できます。
irb(main):011:0> numbers = [1, 2, 3, 4, 5, 6]
=> [1, 2, 3, 4, 5, 6]

irb(main):012:0> first_even = numbers.find { |n| n.even? }
=> 2

irb(main):013:0> over_10 = numbers.find { |n| n > 10 }
=> nil

Enumerableモジュール:イテレーションの力

each, map, select, find といった便利なメソッドは、実は Enumerable(エニューメラブル)というモジュールによって提供されています。

Enumerable はRubyの「Mix-in(ミックスイン)」機能の代表例です。これは、クラスに「混ぜ込む」ことで、そのクラスのインスタンスに特定の機能(メソッド群)を追加する仕組みです。

Enumerable をMix-inするクラス(例えば Array や Hash, Range)が満たすべき契約はただ一つ、each メソッドを実装することです。

each メソッドさえ定義されていれば、Enumerable モジュールは each を使って map, select, find, sort, count など、数十もの便利なイテレーションメソッドを自動的に提供してくれます。

例えば、Array クラスは each を持っています。

Ruby 実行環境
ブラウザ上で動作するRuby3.4のREPL実行環境です。
プロンプト (irb>) の後にコマンドを入力し、Enterキーで実行します。
Ctrl+Cまたは左上の停止ボタンで実行中のコマンドを中断できます。
irb(main):014:0> numbers = [1, 2, 3]
=> [1, 2, 3]
# numbers (Array) は each を持っているので...
irb(main):015:0> numbers.map { |n| n * 2 }  # map が使える
=> [2, 4, 6]
irb(main):016:0> numbers.select { |n| n.odd? } # select が使える
=> [1, 3]

これは、自分で新しいコレクションクラスを作った場合でも同様です。(include については後の「モジュールとMix-in」の章で詳しく学びます)

ファイルを編集:my_collection.rb
# Enumerableモジュールを include する
class MyCollection
  include Enumerable # これがMix-in

  def initialize(items)
    @items = items
  end

  # Enumerable のために each メソッドを定義する
  def each
    @items.each do |item|
      yield(item) # ブロックに要素を渡す
    end
  end
end

collection = MyCollection.new([10, 20, 30])

# each を定義しただけで、map が使える!
doubled = collection.map { |x| x * 2 }
puts "Map result: #{doubled.inspect}"

# select も使える!
selected = collection.select { |x| x > 15 }
puts "Select result: #{selected.inspect}"
ruby my_collection.rb
ブラウザ上で動作するRuby3.4の実行環境です。
左上の実行ボタンを押して、このページ内のmy_collection.rbに書かれている内容を実行します。
Map result: [20, 40, 60]
Select result: [20, 30]

このように、Rubyのイテレータの強力さは Enumerable モジュールによって支えられています。Rubyでは、「each メソッドを持つものは、すべて Enumerable である(あるいはそう振る舞える)」という考え方が非常に重要です。

for ループとの比較

他言語経験者の方は、for ループを使いたくなるかもしれません。

// C や Java の for ループ
for (int i = 0; i < 3; i++) {
    printf("Hello\n");
}

Rubyにも for 構文は存在します。

Ruby 実行環境
ブラウザ上で動作するRuby3.4のREPL実行環境です。
プロンプト (irb>) の後にコマンドを入力し、Enterキーで実行します。
Ctrl+Cまたは左上の停止ボタンで実行中のコマンドを中断できます。
irb(main):014:0> numbers = [1, 2, 3]
=> [1, 2, 3]

irb(main):015:0> for num in numbers
irb(main):016:1* puts num
irb(main):017:1> end
1
2
3
=> [1, 2, 3]

しかし、Rubyの世界では for ループはほとんど使われません。なぜなら、for は内部的に each メソッドを呼び出しているに過ぎないからです。

Rubyプログラマは、for よりも each などのイテレータをブロックと共に使うことを圧倒的に好みます。イテレータの方が、何をしているか(単なる繰り返し、変換、選択など)がメソッド名 (each, map, select) から明確であり、コードが読みやすくなるためです。

yield:ブロックを受け取るメソッド

では、どうすればブロックを受け取るメソッドを自分で作れるのでしょうか? それには yield というキーワードを使います。

メソッド内で yield が呼び出されると、そのメソッドに渡されたブロックが実行されます。

ファイルを編集:yield_basic.rb
def simple_call
  puts "メソッド開始"
  yield # ここでブロックが実行される
  puts "メソッド終了"
end

simple_call do
  puts "ブロック内の処理です"
end
ruby yield_basic.rb
ブラウザ上で動作するRuby3.4の実行環境です。
左上の実行ボタンを押して、このページ内のyield_basic.rbに書かれている内容を実行します。
メソッド開始
ブロック内の処理です
メソッド終了

yield はブロックに引数を渡すこともできます。

ファイルを編集:yield_with_args.rb
def call_with_name(name)
  puts "メソッド開始"
  yield(name) # ブロックに "Alice" を渡す
  yield("Bob") # ブロックに "Bob" を渡す
  puts "メソッド終了"
end

call_with_name("Alice") do |n|
  puts "ブロックが #{n} を受け取りました"
end
ruby yield_with_args.rb
ブラウザ上で動作するRuby3.4の実行環境です。
左上の実行ボタンを押して、このページ内のyield_with_args.rbに書かれている内容を実行します。
メソッド開始
ブロックが Alice を受け取りました
ブロックが Bob を受け取りました
メソッド終了

each や map のようなイテレータは、内部でこの yield を使って、コレクションの各要素をブロックに渡しながら実行しているのです。

この章のまとめ

  • ブロックは、メソッドに渡せるコードの塊で、{}(1行)または do...end(複数行)で記述します。
  • イテレータは、ブロックを受け取り、要素の繰り返し処理を行うメソッドです(each, map, select など)。
  • Enumerableモジュールは、 each を実装するクラスに map や select などの強力なイテレーション機能を提供します。
  • Rubyでは for ループよりもイテレータが好まれます。
  • ブロックは |arg| で引数を受け取ることができ、ブロックの最後の式の値が戻り値となります。
  • 自作メソッド内で yield を使うと、渡されたブロックを実行できます。

練習問題1

数値の配列 [1, 2, 3, 4, 5] があります。map イテレータとブロックを使って、各要素を文字列に変換し(例: 1 → "1")、 "1", "2", "3", "4", "5" という文字列の配列を作成してください。

ファイルを編集:practice6_1.rb
array = [1, 2, 3, 4, 5]
ruby practice6_1.rb
ブラウザ上で動作するRuby3.4の実行環境です。
左上の実行ボタンを押して、このページ内のpractice6_1.rbに書かれている内容を実行します。

練習問題2

文字列の配列 ["apple", "banana", "cherry", "date"] があります。select イテレータとブロックを使って、文字数が5文字以上の果物だけを抽出した新しい配列(["apple", "banana", "cherry"])を作成してください。

ファイルを編集:practice6_2.rb
array = ["apple", "banana", "cherry", "date"]
ruby practice6_2.rb
ブラウザ上で動作するRuby3.4の実行環境です。
左上の実行ボタンを押して、このページ内のpractice6_2.rbに書かれている内容を実行します。
前のページ« コレクション (Array, Hash, Range)
次のページクラスとオブジェクト »