본문 바로가기
Web development/Ruby

[Ruby] Block vs Proc vs Lambda

by 자몬다 2019. 6. 18.
  • Block
    • 루비에서 클로저를 사용하는 방법. do~end사이의 코드로 표현됨.
    • 메서드에 블록을 넘겨주는 경우 yield로 실행할 수 있다.
    • &operator를 통해 지역변수 대신 블록에 대한 참조를 인자로 전달 가능
    • return과 break가 블록 안으로 한정된다.

 

  • Proc
    • 익명함수(절차)를 담은 객체. call로 호출한다는 차이점이 있음.
    • 블럭에 있는 코드를 여러 곳에서 사용하려고 할 때 사용
    • 값을 반환하면 메서드가 중단됨. proc이 있는 메서드의 최종 반환값은 Proc의 반환값이 됨.
      • code snippet형태로 작동하므로...

 

  • Lambda
    • 메서드의 매개변수 형태로 코드를 직접 전달. 
    • Proc과의 차이점은 매개변수의 갯수가 맞지 않으면 argument에러를 반환함.
    • (Proc은 값 반환하면 메서드를 중단하지만)Lambda는 반환 후에도 메서드가 계속됨.
      • 그러므로 lambda반환값을 받아서 메서드에서 처리하는게 가능.

 

결론

다른곳에서 재사용할 일 없는 코드 -> Block 사용

여러 곳에서 블럭에 있는 코드를 사용할 것이고, 블럭의 결과값을 그대로 반환할 때 -> Proc 사용

여러 곳에서 블럭에 있는 코드를 사용할 것이지만, 블럭의 결과값을 활용할 필요가 있을 때 -> Lambda 사용

코드블럭에 전달할 매개변수 갯수가 확실하지 않을 때 -> Proc 사용

 

# Block만 사용함. 재사용 불가.
class Array
  def iterate!
    self.each_with_index do |n, i|
      self[i] = yield(n) #yield로 블록 전달
    end
  end
end

array1 = [1,2,3,4,5]
array2 = [6,7,8,9,10]


array1.iterate! do | n |
    n ** 2
end

array2.iterate! do | n |
    n ** 2
end
===========================================
# Proc 쓸때. 재사용이 가능하다는 장점이 있음. 
class Array
  def iterate!(code) # Proc을 전달할 수 있음
    self.each_with_index do |n, i|
      self[i] = code.call(n) #call로 전달
    end
  end
end

array1 = [1,2,3,4,5]
array2 = [6,7,8,9,10]

square = Proc.new do |n|
    n ** 2
end

array1.iterate!(square)
array2.iterate!(square)

https://www.joinc.co.kr/w/Site/Ruby/ProcsLambdaBlocks

댓글