Continuation 클래스
Continuation 클래스
Continuation 객체는 continuation을 require한 뒤 Kernel#callcc로 생성돼요. 이 객체는 복귀 주소와 실행 컨텍스트를 담고 있어서, 프로그램 어디에서든 callcc 블록의 끝으로 비지역 반환(nonlocal return)을 할 수 있게 해줘요. 연속은 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
}
puts
이 코드는 다음과 같이 출력해요:
0: 0 1 2 3 4
1: 5 6 7 8 9
2: 10 11 12 13 14
3: 15 16
출처: Ruby 3.3 API
본문
인스턴스 메서드
cont[args, ...](call의 별칭) — 연속을 호출해요. 프로그램은callcc블록의 끝에서부터 이어서 실행돼요. 인자가 없으면 원래callcc는nil을 돌려주고, 인자가 하나면 그 값을, 그 외에는 인자를 담은 배열을 돌려줘요.
callcc {|cont| cont.call } #=> nil
callcc {|cont| cont.call 1 } #=> 1
callcc {|cont| cont.call 1, 2, 3 } #=> [1, 2, 3]
call(args, ...)— 인자와 함께 연속을 호출하는 메서드예요.[]라고도 별칭이 붙어 있어요.