Jesse Yoon
2/14/2006 8:24:00 AM
Minkoo,
When you call cont.call, the control goes right back to the end of
callcc block with all the context in tact. So your program's control
flow looks like this:
1. cont = print_num # calls print_num method
2. callcc {|c| return c} # at i % 2 == 0, print_num returns with the
continuation as a return value, which is now assigned to cont
3. puts "Yae..."
4. cont.call # now the control goes back to "}" of callcc with the
variable i == 2
5. for loop continues
6. go to step 2 unless i == 10
7. at i == 10, callcc block returns one final time
8. puts ...
9. cont.call
10. now that i == 10 for loop finishes and the return value of
print_num at this time is (1..10), because "for loop" is essentially
(1..10).each {|i|} in disguise, and #each returns self
11. puts ...
12. cont.call # argh! this time you're calling (1..10).call
13. NoMethodError exception
This is what has happened.
Hope this helps.
Jesse
Minkoo Seo wrote:
> Hi all.
>
> I've written the following code to learn continuations in ruby only to
> fail. Please have a look at:
>
>
> def print_num
> for i in (1..10)
> puts i
> if i % 2 == 0; callcc{|c| return c}; end
> end
> end
>
> cont = print_num
> puts "Yae, I love even~"
> cont.call
> puts "Bye"
>
>
> This code produces:
>
> C:\WINDOWS\system32\cmd.exe /c ruby a.rb
> 1
> 2
> Yae, I love even~
> 3
> 4
> Yae, I love even~
> 5
> 6
> Yae, I love even~
> 7
> 8
> Yae, I love even~
> 9
> 10
> Yae, I love even~
> Yae, I love even~
> a.rb:10: undefined method `call' for 1..10:Range (NoMethodError)
> shell returned 1
> Hit any key to close this window...
>
> This is contrary to my intuition. I've called cont.call only once, and
> cont.call should put the following command, put "bye", into stack. I
> can't figure out the reason why cont.call is called indefinitely.
>
> Best,
> Minkoo Seo