Continuation in ruby

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

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

···

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:

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

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