학습
Ruby 루비의 블록과 람다
Ruby 루비의 블록과 람다 — 중급
루비의 블록과 람다
1. 도입 (왜 배워야 하는가)
루비에서 블록과 람다는 매우 중요한 개념입니다. 이들은 코드의 재사용성을 높이고, 코드의 가독성을 개선하며, 프로그래밍 패러다임인 함수형 프로그래밍을 지원하는 데 필수적입니다. 실무에서는 데이터 처리, 이벤트 처리, 비동기 작업 등 다양한 곳에서 이 기능들이 사용됩니다.
블록과 람다를 모르면, 복잡한 로직을 구현할 때 코드가 길어지고 복잡해져 관리하기 어려워질 수 있습니다. 예를 들어, 여러 요소를 순회하며 특정 조건에 맞는 작업을 수행할 때 블록이나 람다 없이 반복문을 사용하면 코드가 장황해질 수 있습니다.
2. 핵심 개념 설명
블록 (Block)
블록은 루비에서 코드의 묶음을 나타내며, 메서드에 인자로 전달할 수 있습니다. 마치 레시피에서 특정 조리 방법을 묶어놓은 것과 같습니다.
람다 (Lambda)
람다는 블록과 유사하지만, 몇 가지 중요한 차이점이 있습니다. 람다는 독립적인 객체로 취급되며, 매개변수를 엄격하게 검사합니다. 블록은 메서드와 밀접하게 관련되어 있고, 단순히 코드 덩어리입니다.
관련 용어 정리
| 용어 | 설명 |
|---|---|
| 블록 | 메서드에 전달되는 코드 덩어리 |
| 람다 | 블록의 확장으로, 객체로 취급됨 |
| Proc | 람다와 유사하지만, 매개변수 검사 느슨함 |
3. 기본 코드 예제
블록의 기본 사용법은 다음과 같습니다.
def greet
yield("안녕하세요!") if block_given?
end
greet { |message| puts message }
실행 결과
안녕하세요!
코드 한 줄씩 동작 설명
def greet로 메서드를 정의합니다.yield는 메서드에 전달된 블록을 호출합니다.block_given?은 블록이 있는지를 확인합니다.greet메서드를 호출하면서 블록을 전달합니다.- 블록 내부에서
puts message를 통해 블록이 전달한 메시지를 출력합니다. greet_lambda라는 변수를 정의하고, 람다를 할당합니다.call메서드를 통해 람다를 실행합니다.Cart클래스에 장바구니 기능을 구현합니다.add_item메서드로 상품을 추가합니다.total메서드에서 블록을 통해 총 가격을 계산하고 출력합니다.numbers배열에서 짝수를 필터링하기 위해 람다를 사용합니다.select메서드에 람다를 전달하여 짝수만 반환합니다.- 잘못된 코드: 블록이 없으면
yield에서 오류가 발생합니다. - 올바른 코드:
block_given?조건을 확인해야 합니다. - 잘못된 코드: Proc은 인자 수에 관대하지만, 람다는 엄격합니다.
- 올바른 코드: 람다를 사용할 때는 정확한 인자 수를 맞춰야 합니다.
- 블록과 람다는 코드의 재사용성과 가독성을 높여줍니다.
- 블록은 메서드에 종속적이고, 람다는 객체로 취급됩니다.
yield와call메서드를 통해 블록과 람다를 호출합니다.- 실무에서 데이터 처리 및 이벤트 처리에 자주 사용됩니다.
- 고급 메서드와 블록 사용법
- 함수형 프로그래밍 패턴
- 루비의 Iterable과 Enumerator 사용법
람다의 기본 사용법은 다음과 같습니다.
greet_lambda = ->(message) { puts message }
greet_lambda.call("안녕하세요!")
실행 결과
안녕하세요!
코드 한 줄씩 동작 설명
4. 실전 활용 예제
쇼핑몰에서 장바구니 구현하기
장바구니에 추가된 상품의 가격을 계산할 때 블록을 사용할 수 있습니다.
class Cart
def initialize
@items = []
end
def add_item(item)
@items << item
end
def total(&block)
total_price = @items.inject(0) { |sum, item| sum + item[:price] }
block.call(total_price) if block
end
end
cart = Cart.new
cart.add_item({ name: "사과", price: 2000 })
cart.add_item({ name: "배", price: 3000 })
cart.total { |total| puts "총 금액: #{total}원" }
실행 결과
총 금액: 5000원
코드 설명
데이터 처리에서의 람다 사용
데이터를 필터링할 때 람다를 사용할 수 있습니다.
numbers = [1, 2, 3, 4, 5]
filter_even = ->(num) { num.even? }
even_numbers = numbers.select(&filter_even)
puts even_numbers
실행 결과
2
4
코드 설명
5. 흔한 실수와 주의사항
실수 1: 블록이 없을 때의 오류
def greet
yield("안녕하세요!")
end
greet # 오류 발생
실수 2: 람다와 Proc 혼동
proc_example = Proc.new { |x| x + 1 }
lambda_example = ->(x) { x + 1 }
proc_example.call(1, 2) # No error
lambda_example.call(1, 2) # ArgumentError