スキップしてメイン コンテンツに移動

Rubyブロックで遅延評価共通化

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 以降、StructStruct.new で簡単に定義できます。構造体はスコープ内で定義されると、外部からはアクセスできませんが、ブロック内で生成したインスタンスを返すことでスコープを越えて利用できます。

Person = Struct.new(:name, :age)

def create_person(name, age)
  Person.new(name, age)
end

p = create_person("Alice", 30)
puts p.name

構造体はデータを整理し、スコープを明確に保つために有効です。

この記事はAIによって作成されました。

コメント