1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
describe :continuation_call, :shared => true do
# TODO: fix these specs
it "using #call transfers execution to right after the Kernel.callcc block" do
array = [:reached, :not_reached]
cont = callcc { |cc| cc }
unless array.first == :not_reached
array.shift
cont.call
end
array.should == [:not_reached]
end
it "arguments given to #call (or nil) are returned by the Kernel.callcc block (as Array unless only one object)" do
Kernel.callcc {|cc| cc.call}.should == nil
Kernel.callcc {|cc| cc.call 1}.should == 1
Kernel.callcc {|cc| cc.call 1, 2, 3}.should == [1, 2, 3]
end
it "#[] is an alias for #call" do
Kernel.callcc {|cc| cc.call}.should == Kernel.callcc {|cc| cc[]}
Kernel.callcc {|cc| cc.call 1}.should == Kernel.callcc {|cc| cc[1]}
Kernel.callcc {|cc| cc.call 1, 2, 3}.should == Kernel.callcc {|cc| cc[1, 2, 3]}
end
it "closes over lexical environments" do
o = Object.new
def o.f; a = 1; Kernel.callcc {|c| a = 2; c.call }; a; end
o.f().should == 2
end
it "escapes an inner ensure block" do
a = []
cont = nil
a << :pre_callcc
Kernel.callcc do |cc|
a << :in_callcc
cont = cc
end
a << :post_callcc
unless a.include? :pre_call
begin
a << :pre_call
cont.call
a << :post_call
ensure
a << :ensure
end
end
a.should == [:pre_callcc,:in_callcc,:post_callcc,:pre_call,:post_callcc]
end
it "executes an outer ensure block" do
a = []
cont = nil
begin
a << :pre_callcc
Kernel.callcc do |cc|
a << :in_callcc
cont = cc
end
a << :post_callcc
unless a.include? :pre_call
a << :pre_call
cont.call
a << :post_call
end
ensure
a << :ensure
end
a.should == [:pre_callcc,:in_callcc,:post_callcc,:pre_call,:post_callcc,:ensure]
end
end
|