이들은 Ruby가 코드 덩어리를 데이터로 다루는 세 가지 방식입니다. block은 메서드에 전달되며(객체가 아님); Proc과 lambda는 block을 감싸는 객체입니다(호출 가능, 저장 가능). proc과 lambda는 인자 검사와 return 동작에서 미묘하게 다릅니다.
block — 메서드에 전달됨 (객체가 아님)
[, , ].each { || puts n }
block은 메서드에 전달되는 코드({ } 또는 do...end)입니다 — 저장할 수 있는 독립 객체가 아니며, 메서드 호출에 묶여 있습니다.
# Proc — block을 저장하고 호출할 수 있는 객체로 변환
square = Proc.new { |x| x * x }
square.call(5) # 25
square.(5) # 25 (대체 호출 문법)
# lambda — 마찬가지로 호출 가능한 객체 ("더 엄격한" Proc)
double = lambda { |x| x * 2 }
double = ->(x) { x * 2 } # -> "stabby lambda" 문법
double.call(5) # 10
proc과 lambda는 block을 변수에 할당하고, 전달하고, 나중에 호출(.call)할 수 있는 객체로 감쌉니다 — 재사용 가능한 동작을 저장하는 데 유용합니다.
1. 인자 검사:
lambda → 엄격: 인자 개수가 틀리면 에러 (메서드처럼)
proc → 관대: 추가 인자 무시, 누락은 nil로 채움
2. RETURN 동작:
lambda → `return`은 LAMBDA에서 반환 (일반 메서드처럼)
proc → `return`은 감싸는 메서드에서 반환 (놀랄 수 있음!)
def test_proc
p = Proc.new { return 10 }
p.call # test_proc 전체에서 반환됨 → 10
return 20 # 도달하지 않음!
end
def test_lambda
l = lambda { return 10 }
l.call # LAMBDA에서만 반환됨 → 10
return 20 # 도달함 → test_lambda는 20 반환
end
가장 중요한 차이: lambda는 메서드처럼 동작(엄격한 인자, return이 lambda만 빠져나감)하는 반면, proc은 더 관대(인자 불일치를 무시하고, return이 감싸는 메서드를 빠져나감 — 놀라운 동작을 일으킬 수 있음)합니다. 일반적으로 lambda가 선호됩니다 — 메서드 같은 예측 가능한 동작 때문입니다.
block, proc, lambda를 이해하는 것 — 특히 그 차이를 — 은 Ruby가 코드를 데이터로 다루는 방식에 대한 깊은 이해를 반영하는 중요한 Ruby 지식입니다. block이 가장 흔하며(반복과 콜백을 위해 메서드에 전달됨 — Ruby의 대표적 기능), proc과 lambda는 block을 변수에 할당하고, 전달하고, 나중에 호출할 수 있는 저장 가능하고 재사용 가능한 객체로 변환합니다(동작 저장, 함수형 패턴 구축, 콜백을 값으로 전달하는 데 유용).
proc과 lambda의 핵심 차이는 미묘하지만 중요하며 빈번한 면접 주제입니다: 인자 검사(lambda는 메서드처럼 엄격, proc은 관대)와 특히 return 동작(lambda의 return은 lambda만 빠져나가지만, proc의 return은 감싸는 메서드를 빠져나감 — 놀랍고 디버깅하기 어려운 동작을 일으킬 수 있음)입니다.
이 구분 — lambda는 메서드처럼 동작(엄격하고, 예측 가능하며, 지역적 반환)하고 proc은 더 관대하며 놀라운 반환 의미를 가짐 — 을 이해하는 것은 이들을 올바르게 사용하고, 예측 가능하고 메서드 같은 동작 때문에 lambda를 선호하라는 흔한 권장을 이해하는 데 중요합니다.
block은 일상적인 Ruby이고 proc/lambda는 저장 가능한 콜백과 함수형 패턴에 사용되지만, 세 가지 모두(특히 proc 대 lambda의 반환 및 인자 차이)를 이해하는 것은 탄탄한 Ruby 지식을 반영하고, proc-return 함정을 피하는 데 도움이 되며, Ruby가 코드를 객체로 다루는 방식을 진정으로 이해하는 개발자를 구별하는 고전적인 면접 주제입니다.