Rubyブロックで遅延評価共通化
Ruby基礎とブロックの基本
Rubyではメソッドにブロックを渡すことで、実行時にコードを動的に注入できます。ブロックは do...end または {...} で記述し、メソッド内部で yield を呼び出すことで実行されます。ブロックは無名関数として扱われ、呼び出し側のスコープを保持します。
def greet
puts "Hello"
yield if block_given?
puts "Goodbye"
end
greet { puts "Inside block" }
上記例では yield がブロックを実行し、メソッドの流れを制御します。
yieldとブロック付きメソッド
ブロック付きメソッドは yield を使って呼び出し側に処理を委譲します。引数を渡す場合は yield(arg1, arg2) のように書き、ブロック側で |a, b| と受け取ります。
def calculate(a, b)
result = a + b
yield(result) if block_given?
end
calculate(3, 4) { |sum| puts "Sum is #{sum}" }
このパターンはコールバックとしても機能し、柔軟な処理を実現します。
コールバックと引数受渡し
コールバックはメソッドにブロックを渡すことで実装され、引数受渡しは yield で行います。ブロックは呼び出し側のローカル変数を参照できるため、データの受け渡しが簡単です。
def process(items)
items.each do |item|
yield(item) if block_given?
end
end
process([1,2,3]) { |n| puts n * 2 }
このように、コールバックは処理の共通化に役立ちます。
共通化と遅延評価
ブロックを使うことで処理を遅延評価できます。例えば、Enumerator を利用すると、必要になったときだけ計算が実行されます。
enum = Enumerator.new do |y|
1.upto(10) { |i| y << i }
end
enum.each { |n| puts n if n.even? }
このパターンはメモリ効率を高め、共通化されたロジックを再利用可能にします。
構造体とスコープ
Ruby 3.0 以降、Struct は Struct.new で簡単に定義できます。構造体はスコープ内で定義されると、外部からはアクセスできませんが、ブロック内で生成したインスタンスを返すことでスコープを越えて利用できます。
Person = Struct.new(:name, :age)
def create_person(name, age)
Person.new(name, age)
end
p = create_person("Alice", 30)
puts p.name
構造体はデータを整理し、スコープを明確に保つために有効です。
コメント
コメントを投稿