Forum: Ruby Continuation in ruby

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
47b36de21d7ecbc824c81d24802a6290?d=identicon&s=25 Minkoo Seo (Guest)
on 2006-02-14 08:26
(Received via mailing list)
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
F1ae87d23c050dbad815489dbde2f226?d=identicon&s=25 G.Durga Prasad (Guest)
on 2006-02-14 09:25
(Received via mailing list)
On 2/14/06, Minkoo Seo <minkoo.seo@gmail.com> wrote:
> Hi all.
>
> I've written the following code to learn continuations in ruby only to
> fail. Please have a look at:
>

From another learner
Look at my following try
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"
   end
        return nil
end

cont = print_num
puts "Yae, I love even~"
cont.call if cont
puts "Bye"

Hope this helps
Prasad
Fa54609e96f0181158aaf5e53a1c4c6f?d=identicon&s=25 Jesse Yoon (Guest)
on 2006-02-14 09:28
(Received via mailing list)
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
47b36de21d7ecbc824c81d24802a6290?d=identicon&s=25 Minkoo Seo (Guest)
on 2006-02-14 10:54
(Received via mailing list)
Now I get it.

So the continuation returned from print_num by cont = print_num
contains not only the context within print_num method, but also the
context of "cont = print_num". In other words, cont contains (1)
print_num was called, (2) location within print_num, (3) and variables
in its stack.

Thank you, folks.

Best,
Minkoo Seo
This topic is locked and can not be replied to.