Continuation 클래스
Continuation 클래스
Continuation 객체는 continuation을 require한 뒤 Kernel#callcc로 만들어져요. 반환 주소와 실행 컨텍스트를 품고 있어서, 프로그램 어디서든 callcc 블록의 끝으로 비지역적(nonlocal) 반환을 할 수 있게 해 줘요. C의 setjmp/longjmp를 구조화한 것과 비슷하다고 볼 수 있는데, 상태를 더 많이 담으니 스레드에 더 가깝다고 생각해도 돼요.
출처: Ruby 4.0 API
본문
Continuation 은 Kernel#callcc 로 생성돼요. 반환 주소와 실행 컨텍스트를 담고 있어, 프로그램 어디서나 callcc 블록의 끝으로 비지역적 반환을 할 수 있게 해 줘요. 이는 C 의 setjmp/longjmp 를 구조화한 버전과 유사하다고 볼 수 있어요 (그래도 더 많은 상태를 포함하므로 스레드에 더 가깝다고 생각할 수 있어요).
예를 들어:
require "continuation"
arr = [ "Freddie", "Herbie", "Ron", "Max", "Ringo" ]
callcc{|cc| $cc = cc}
puts(message = arr.shift)
$cc.call unless message =~ /Max/
출력:
Freddie
Herbie
Ron
Max
callcc를 다른 메서드 안에서도 호출할 수 있어요:
require "continuation"
def g
arr = [ "Freddie", "Herbie", "Ron", "Max", "Ringo" ]
cc = callcc { |cc| cc }
puts arr.shift
return cc, arr.size
end
def f
c, size = g
c.call(c) if size > 1
end
f
이 (다소 인위적인) 예시는 안쪽 루프가 처리 중간에 일찍 포기하도록 만들어 줘요:
require "continuation"
callcc {|cont|
for i in 0..4
print "#{i}: "
for j in i*5...(i+1)*5
cont.call() if j == 17
printf "%3d", j
end
end
}
p