💎
【Ruby 5日目】基本文法 - イテレータとブロック
はじめに
Rubyの最も強力な機能の一つであるイテレータとブロックについて解説します。
基本概念
ブロックは{}またはdo...endで囲まれたコードの塊です。メソッドに渡すことができ、yieldで実行されます。
イテレータはブロックを受け取って反復処理を行うメソッドです。each、map、select、rejectなどが代表的です。
使い方
# ブロックの基本
[1, 2, 3].each do |num|
puts num
end
# 1行なら{}を使用
[1, 2, 3].each { |num| puts num }
# ブロック付きメソッドの定義
def repeat(n)
n.times { yield }
end
repeat(3) { puts "Hello" }
# ブロック引数
def greet
yield("Alice", 25)
end
greet do |name, age|
puts "#{name}さん、#{age}歳"
end
よくあるユースケース
主要なイテレータメソッド
numbers = [1, 2, 3, 4, 5]
# map: 変換して新しい配列を返す
doubled = numbers.map { |n| n * 2 }
p doubled #=> [2, 4, 6, 8, 10]
# select: 条件に合う要素を抽出
evens = numbers.select { |n| n.even? }
p evens #=> [2, 4]
# reject: 条件に合わない要素を抽出
odds = numbers.reject { |n| n.even? }
p odds #=> [1, 3, 5]
# reduce: 累積計算
sum = numbers.reduce(0) { |acc, n| acc + n }
p sum #=> 15
# each_with_object: オブジェクトを渡しながら反復
hash = numbers.each_with_object({}) do |n, h|
h[n] = n * 2
end
p hash #=> {1=>2, 2=>4, 3=>6, 4=>8, 5=>10}
ブロックをProcとして扱う
# &をつけるとブロックをProcオブジェクトとして受け取れる
def execute(&block)
puts "処理開始"
block.call if block
puts "処理終了"
end
execute { puts "メイン処理" }
# Procを変数に格納
double = Proc.new { |x| x * 2 }
p [1, 2, 3].map(&double) #=> [2, 4, 6]
# Symbol#to_procの活用
names = ["alice", "bob", "charlie"]
p names.map(&:upcase) #=> ["ALICE", "BOB", "CHARLIE"]
p names.map(&:capitalize) #=> ["Alice", "Bob", "Charlie"]
注意点とベストプラクティス
- 複数行ならdo...end、1行なら{}を使うのが慣習
- yieldはブロックが渡されない場合エラーになるので、block_given?で確認
- Symbol#to_proc(&:メソッド名)は簡潔で高速
- ブロックは引数ではなく特別な存在(1つのメソッドに1つだけ)
- Procとlambdaの違いを理解する(後日解説)
まとめ
イテレータとブロックについて学びました。実践的なコード例を通じて、Ruby 3.4の機能を活用できるようになりましょう。
Discussion