continuations in ruby (anton vasiljev)
TRANSCRIPT
![Page 1: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/1.jpg)
Continuations
in Ruby
Antono VasiljevRuby Open Air, 2012
![Page 2: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/2.jpg)
Continuation is basicallyRest of the program
![Page 3: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/3.jpg)
Continuations arefirst class objects
in Ruby
![Page 4: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/4.jpg)
irb(main)> c = callcc { |cont| cont } => #<Continuation:0x7f70ad16d030>
![Page 5: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/5.jpg)
Continuations are about
Flow Control
![Page 6: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/6.jpg)
1: i = 02: callcc do |cont|3: i = 14: cont.call 5: i = 2 # skipped6: end7:8: # i => 1
![Page 7: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/7.jpg)
1: i = 02: i = callcc do |cont|3: i = 14: cont.call(2)5: i = 3 # skipped6: end7:8: # i => 2 # See lines: 2, 4
![Page 8: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/8.jpg)
1| i = 02|3| label :sum4|5| puts i += 16|7| goto :sum, cond: (i < 10)
![Page 9: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/9.jpg)
1| LABELS = {}2|3| def label(name)4| callcc { |cont| LABELS[name] = cont }5| end6| 7| def goto(label, args: {})8| LABELS[label].call if args[:cond]9| end
![Page 10: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/10.jpg)
Continuation are likegoto
with parameters(but jumps only backward)
![Page 11: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/11.jpg)
continuations jumps fardef foo
barenddef bar bazenddef baz
$cont[0]end
callcc { |c| $cont = c; foo }
![Page 12: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/12.jpg)
Similar to exceptions.But can go down through stack.
Time Machine!
![Page 13: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/13.jpg)
Restartable Exceptions
![Page 14: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/14.jpg)
1| begin2| hello3| rescue Exception => e4| e.restart5| ensure6| e.cleanup7| end
![Page 15: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/15.jpg)
1| def hello3| i = 04| restartable do5| puts i += 16| raise Exception unless i == 57| end8| end
![Page 16: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/16.jpg)
1| def restartable2| cont = callcc { |c| c }3| begin4| yield5| rescue Exception => e6| e.continuation = cont7| raise e8| end9| end
![Page 17: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/17.jpg)
require 'continuation'
class Exception class << self attr_accessor :conts end
def continuation=(cont) self.class.conts ||= {} self.class.conts[self.class] ||= cont end
![Page 18: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/18.jpg)
def restart self.class.conts[self.class].call end
def cleanup self.class.conts.delete(self.class) endend
![Page 19: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/19.jpg)
You can do with continuation:
Generator objectsFibers/CoroutinesExit from recursion
Other control structures
![Page 20: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/20.jpg)
Thanks!
![Page 21: Continuations in Ruby (Anton Vasiljev)](https://reader031.vdocuments.net/reader031/viewer/2022020207/5561929fd8b42a91778b5290/html5/thumbnails/21.jpg)
http://antono.info/