Continuation in Ruby

Tags:

Continuation이란건 Sebesta 의 Programming Language 이후에 처음보네요.

def print_num 
   for i in (1..10) 
       puts i 
       if i % 2 == 0;  callcc{|c| return c}; end 
       puts "** cont.call brings you here"  # 물론 cont는 call 시 여기로 옵니다.
   end 
   return nil 
end 

cont = print_num  # cont 에는 이 사실도 저장됨
puts "Yae, I love even~" 
cont.call if cont 
puts "Bye" 

실행결과는 다음과 같습니다.
C:\WINDOWS\system32\cmd.exe /c ruby a.rb
1
** cont.call brings you here
2
Yae, I love even~
** cont.call brings you here
3
** cont.call brings you here
4
Yae, I love even~
** cont.call brings you here
5
** cont.call brings you here
6
Yae, I love even~
** cont.call brings you here
7
** cont.call brings you here
8
Yae, I love even~
** cont.call brings you here
9
** cont.call brings you here
10
Yae, I love even~
** cont.call brings you here
Yae, I love even~
Bye
Hit any key to close this window…

이게 굉장히 헷갈리기가 쉬운데.. cont=print_num을하고 print_num안에서 callcc 로 closure를 만들때 print_num 을 호출하는 부분 역시 저장됩니다. 즉, “cont=print_num”을 했다는 사실과 print_num안에서의 컨텍스트가 저장되죠. 따라서 cont.call은 코드는 하나있지만 되지만 실행은 여러번 됩니다.

Comments

5 responses to “Continuation in Ruby”

  1. 무책 Avatar

    좀 더 정확히는 puts “**…” 부분으로 온다기 보다는 그 바로 윗줄의 return c 와 } 사이로 떨어진다고 보는 것이 맞습니다. 그 사실을 이용한 continuation을 쓰는 대표적인 용법이 아래와 같습니다.

    if cont = callcc { |c| c }
    # 처음 설정시 필요한 일
    else
    # 이후 cont.call로 왔을 때 해야할 일
    end

    이렇게 하고 나중에 cont.call 로 부르게 되면 call의 인자가 nil로 되어 c 와 } 사이로 가게 되고 결국 그 nil이 맨 마지막으로 evaluation되기 때문에 cont == nil이 되어 else 이후 문장이 실행되는 것입니다. 만약 cont.call(“hello”)라고 부른다면 처음 처럼 if문 바로 다음으로 가게 되고 이 때 cont == “hello”가 되겠죠.

    Jesse

  2. MKSeo Avatar
    MKSeo

    한국사람같던데 역시군요 ㅋㅋ 반가워요 Jesse ^^; 예제는 감사히 보았습니다. 그런데 그런 용례가 대표적이라니;;; 뭐랄까 너무 해커 같은 코드네요..

    Beyond Java보셨나요? 저는 거기에 나오는 Seaside 와 같은 continuation을 사용한 c/s software작성이 흥미롭더군요.. 이 외에도 O/S 쪽에서도 continuation 을 사용한 페이퍼들이 많던데 그런 아이디어들을 반영시킨 라이브러리를 생각해봐도 재밌을거 같고요..

    또는 자바나 C++로 동일한 아이디어를 구현하는 방법도 흥미롭고요..

  3. 무책 Avatar

    네, 저도 반갑습니다. MKSeo님 블로그 재밌게 잘 읽고 있습니다.

    해커스럽다기 보다는 아마도 C 시절부터 내려오는 setjmp/longjmp convention이 아닌가 생각합니다. Programming Ruby 설명을 비롯해서 Ruby Standard 라이브러리 소스까지 거의 대부분 저런 형태로 callcc를 사용하고 있답니다.

  4. MKSeo Avatar
    MKSeo

    흐흐. 저도 나름대로 C오래했다고 생각했는데 그 setjmp/longjmp 는 잘몰라요. 찾아봐야겠군요.

  5. CN Avatar

    setjmp와 longjmp를 보실 때 C언어로 구현한 try catch 소스를 보시는 것도 흥미로울 것 같습니다. 추천드립니다. :-)

Leave a Reply

Your email address will not be published. Required fields are marked *