**yield**는 메서드에 전달된 block을 호출합니다 — block으로 제어를 넘기며, 선택적으로 값을 전달한 다음, 메서드를 재개합니다. 이는 메서드가 자신에게 주어진 block을 호출하는 방식이며, Ruby의 반복과 많은 우아한 패턴의 배후 메커니즘입니다.
기본 yield — 주어진 block 호출
puts
puts
greet { puts }
메서드가 yield를 호출하면, 자신에게 전달된 block({ } 또는 do...end)을 실행합니다. 메서드가 block이 언제(그리고 몇 번) 실행될지 제어합니다.
def each_pair
yield("a", 1) # block의 매개변수에 값 전달
yield("b", 2)
end
each_pair { |key, value| puts "#{key}: #{value}" }
# 출력: a: 1 / b: 2
yield(args)는 block의 매개변수(|key, value|)에 값을 전달합니다 — 이것이 반복 메서드가 각 요소를 block에 주는 방식입니다.
def my_each(array)
i = 0
while i < array.length
yield(array[i]) # 각 요소를 block에 yield
i += 1
end
end
my_each([1, 2, 3]) { |n| puts n * 2 } # 2, 4, 6
# 이것이 본질적으로 Array#each가 내부적으로 동작하는 방식입니다!
이는 Ruby의 반복 메서드(each, map 등)가 내부적으로 동작하는 방식을 보여줍니다 — 각 요소를 block에 yield합니다.
def maybe_yield
if block_given? # block이 전달됐는지 확인 (에러 방지)
yield
else
"no block"
end
end
# block을 매개변수로 명시적으로 포착 (&로)
def run(&block) # &block은 block을 Proc 객체로 포착
block.call # 명시적으로 호출
end
block_given?은 block이 전달됐는지 확인하고(LocalJumpError 방지), &block은 block을 저장하거나 전달할 수 있는 Proc 객체로 포착합니다.
yield를 이해하는 것은 중요한 Ruby 지식입니다 — 메서드가 block을 호출하는 메커니즘으로, Ruby의 대표적인 반복과 많은 우아한 패턴을 떠받치므로, 이를 파악하면 Ruby의 상당 부분이 실제로 어떻게 동작하는지 밝혀집니다. yield는 메서드에 전달된 block을 호출하는데(제어를 넘기며 선택적으로 값을 전달), 이것이 바로 Ruby의 반복 메서드(each, map, select)가 내부적으로 동작하는 방식입니다 — 각 요소를 block에 yield합니다.
이를 이해하면 Ruby의 block 기반 반복이 명확해지고 block을 받는 자신만의 메서드를 작성할 수 있게 됩니다 — 표현력 있는 API, 커스텀 반복자, 리소스 관리 메서드(block 주변의 설정/정리), DSL을 만드는 강력한 역량입니다.
yield(block 호출, block에 인자 전달), block_given?(block이 전달됐는지 안전하게 확인, 에러 방지), &block(block을 Proc로 명시적 포착)을 아는 것은 Ruby의 반복과 block을 받는 메서드가 어떻게 동작하는지 이해하고 자신만의 block 기반 메서드를 작성하는 데 모두 중요합니다.
block은 Ruby의 중심이고 yield는 메서드가 이를 사용하는 방식이므로, yield를 이해하면 Ruby의 가장 독특한 기능(block)에 대한 파악이 깊어지고, Ruby를 표현력 있게 만드는 우아한 block 수용 메서드를 작성할 수 있게 됩니다 — 깔끔한 API를 구축하는 데 귀중한 기술이자, Ruby의 block 메커니즘이 내부적으로 실제 어떻게 기능하는지에 대한 이해를 반영하는 흔한 면접 주제입니다.