Header

  1. View current page

    딥뿔이 자라나는 노트

Profile_image?t=1225424611&type=big
나를 바꾼 똑똑한 생활 습관, 스프링노트 - 여러분도 지금 시작해보세요!
38

루비 1.9의 새로운 블럭 문법

루비 1.9.0 - 크리스마스 선물!에서 바뀐 문법 중 가장 눈에 띄는 부분은 바로 블럭과 관련한 부분이다.

 

block local variables

루비 문법 중 가장 어색한 부분 중 하나가 블럭안에서 정의한 변수의 범위(scope)에 관한 것이었다. 아래 코드를 보자.

 

  1. lambda {d = 2; puts d }.call

 

위 문장을 실행한 후 d를 출력해보면 1.8에서는 2가 출력된다. 블럭이 따로 이름 공간을 갖지 않기 때문이다. 하지만 1.9에서는 NameError가 발생한다. 이제야 블럭 지역 변수가 생긴 것이다.

 

또 하나, 블럭 인자의 범위도 문제였다.

 

  1. a = 1
    10.times{|a| puts a}
    puts a

 

믿기 어렵겠지만, 1.8에서 마지막 문장의 결과로 '9'가 출력된다. 블럭 매개 변수마저도 이름 공간이 따로 없었던 것이다.

하지만 1.9에서 같은 예제를 실행해보면 1이 출력됨을 볼 수 있다.

 

프로그래밍 루비를 번역하면서도 여러번 지적한 적이 있는 루비의 어두운 단면 중 하나인데, 깔끔하게 정리가 되어 다행이다.

 

lambda != proc

1.8에서 lambda와 proc은 완전히 같다. 하지만 1.9에서는 그 의미가 달라졌다.

결론부터 이야기하면 lambda는 람다, proc은 블록 문법을 따른다. 그리고 그 차이는 매개변수 개수를 검사하는 로직에 있다.

 

  1. def test
     yield 1
    end

    test {|a,b|}

 

위 코드에서는 test 메서드에 블럭을 바인딩하는데 이 블럭이 매개변수를 2개(a,b) 사용한다. 그런데 yield 할 때는 값을 한개만 넘겨준다. 그렇게 하면 자연스럽게 a=1, b=nil이 매핑된다. 이것이 1.8 이후 버전에서 공통적으로 적용되는 블럭 매커니즘이다.

 

그리고 루비 1.9의 proc은 이 의미를 잘 따른다.

 

  1. irb(main):036:0>  proc {|a,b| a.to_i+b.to_i}.call(1)
    ArgumentError: wrong number of arguments (1 for 2)

 

1.8에서는 위처럼 매개변수 개수가 잘못되었다는 에러가 발생하지만, 1.9에서는 블럭 문법처럼 잘 동작한다.

 

  1. irb(main):003:0> proc {|a,b| a.to_i+b.to_i}.call(1)
    => 1

 

물론, 1.9에서도 lambda 객체는 ArgumentError를 발생시킨다.

 

  1. irb(main):005:0> lambda {|a,b| a.to_i+b.to_i}.call(1)
    ArgumentError: wrong number of arguments (1 for 2)

 

축약 문법

마츠의 발표 중에 재미있는 화면이 있어서 소개한다.

 

mgp00026.jpg

출처: http://www.rubyist.net/~matz/slides/kobe07/index.html

 

왜 뜬금없이 -> 라는 문법이 추가되었을까 고민 중이었는데, 바로 저런 이유였다. ->이 람다와 비슷하게 생겼다는 것이다. C언어에서는 레퍼런스의 메서드 호출에 사용하는 문법인데, 좀 어색하기는 하지만 저런 설명을 듣고보니 그럴 듯 해 보이기도 한다.

 

그런 이유로 1.9에서는 이런 축약 표현이 가능해졌다.

 

  1. lambda {|a,b| a+b}.call(1,2)
    ->(a,b){a+b}.(1,2)

 

위 문장과 아래 문장은 같다. lambda 대신 ->를 쓸 수 있게 되었고 Proc#call을 .으로 줄여쓸 수 있게 되었다. 아직 눈에 익지 않아서 가독성이 좋은지는 잘 모르겠다. IDE가 ->를 람다로 바꿔서 보여주면 좋을 것 같다 :)

 

 

 

History

Last edited on 12/26/2007 15:21 by deepblue

Comments (0)

You must log in to leave a comment. Please sign in.