Slide 1

Slide 1 text

Brony User Group Cologne hosted by 15.05.2013

Slide 2

Slide 2 text

Ruby #666 Black Magic

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Continuations, Fibers and friends Black Magic aka

Slide 5

Slide 5 text

Continuations callcc { |cc| $keynote = cc }

Slide 6

Slide 6 text

Ich stehe vor dem Kühlschrank und möchte mir gern ein Sandwich machen.

Slide 7

Slide 7 text

Als erstes erzeuge ich eine Continuation…

Slide 8

Slide 8 text

Ich hole Käse, Butter, Mayo, Schinken und das Brot aus dem Kühlschrank.

Slide 9

Slide 9 text

Ich mache mir das Sandwich, alle Zutaten sind verarbeitet.

Slide 10

Slide 10 text

Ich rufe die Continuation auf.

Slide 11

Slide 11 text

Ich stehe vor dem Kühlschrank und möchte mir gern ein Sandwich machen.

Slide 12

Slide 12 text

Der Kühlschrank ist leer, aber da liegt ja ein fertiges Sandwich auf dem Tisch.

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

Quasi deprecated in Ruby 1.9 (müssen explizit geladen werden) Es gibt eine Klasse Continuation Continuations sind ein bisschen wie goto-Statements Können nur nach “hinten” springen Können den lokalen Scope verlassen – Der Stack zum Zeitpunkt der Definition wird wieder hergestellt

Slide 15

Slide 15 text

require 'continuation' @counter = 0 def foo puts "foo: #{caller.inspect}" bar end def bar callcc { |cc| $ref = cc } puts "bar: #{caller.inspect}" puts "counter: #{@counter}" end def callme $ref.call if @counter < 2 puts "callme: #{caller.inspect}" end foo @counter += 1 callme # foo: ["cont_stack.rb:21:in `'"] # bar: ["cont_stack.rb:7:in `foo'", "cont_stack.rb:21:in `'"] # counter: 0 # bar: ["cont_stack.rb:7:in `foo'", "cont_stack.rb:21:in `'"] # counter: 1 # callme: ["cont_stack.rb:25:in `'"]

Slide 16

Slide 16 text

Beispiele Seaside - Webframework in Smalltalk Wee - Seaside-ähnliches Webframework in Ruby

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

$keynote.call

Slide 19

Slide 19 text

Continuations, Fibers and friends Black Magic aka

Slide 20

Slide 20 text

Fiber

Slide 21

Slide 21 text

Kernel.throw :throw

Slide 22

Slide 22 text

Continuations, Fibers and friends Black Magic aka

Slide 23

Slide 23 text

Kernel.throw “Transfers control to the end of the active catch block waiting for tag”

Slide 24

Slide 24 text

def foo puts "foo: #{caller.inspect}" catch :lvl3 do throw :lvl1 end end def bar puts "bar: #{caller.inspect}" catch :lvl2 do foo end end def callme puts "callme: #{caller.inspect}" catch :lvl1 do bar end puts "callme: #{caller.inspect}" end catch :lvl0 do callme end

Slide 25

Slide 25 text

Warden Sinatra Rack Testing von verschachtelten Blöcken Beispiele für Kernel.throw

Slide 26

Slide 26 text

Kernel.throw :fibers

Slide 27

Slide 27 text

Fiber

Slide 28

Slide 28 text

Fibers "light weight cooperative concurrency" - Ruby Doc cooperative multitasking vs preemptive scheduling Keine echte Nebenläufigkeit, daher automatisch Thread-Safe Gibt es seit 1.9 Haben einen eigenen Stack

Slide 29

Slide 29 text

@counter = 0 def party puts "party: #{caller.inspect}" end def create_fiber puts ">: #{caller.inspect}" f = Fiber.new do puts "fiber: #{caller.inspect}" @counter += 1 puts "counter: #{@counter}" party end.resume puts "counter: #{@counter}" puts "<: #{caller.inspect}" f end def bar create_fiber end def foo bar end def callme puts "callme: #{caller.inspect}" foo puts "callme after foo: #{caller.inspect}" end puts "counter: #{@counter}" callme # party: ["fiber_stack.rb:15:in `block in create_fiber'"] # >: ["fiber_stack.rb:23:in `bar'", "fiber_stack.rb:27:in `foo'", "fiber_stack.rb:32:in `callme'", "fiber_stack.rb:37:in `'"] # fiber: [] # counter: 1 # counter: 1 # <: ["fiber_stack.rb:23:in `bar'", "fiber_stack.rb:27:in `foo'", "fiber_stack.rb:32:in `callme'", "fiber_stack.rb:37:in `'"] # callme: ["fiber_stack.rb:37:in `'"] # callme after foo: ["fiber_stack.rb:37:in `'"] # counter: 0

Slide 30

Slide 30 text

Wofür?

Slide 31

Slide 31 text

sequence = Enumerator.new do |yielder| number = 0 loop do number += 1 yielder.yield number end end Fiber!

Slide 32

Slide 32 text

require 'eventmachine' require 'em-http' require 'fiber' def async_fetch(url) f = Fiber.current http = EventMachine::HttpRequest.new(url).get :timeout => 10 http.callback { f.resume(http) } http.errback { f.resume(http) } return Fiber.yield end EventMachine.run do Fiber.new{ puts "Setting up HTTP request #1" data = async_fetch('http://www.google.com/') puts "Fetched page #1: #{data.response_header.status}" EventMachine.stop }.resume end # Setting up HTTP request #1 # Fetched page #1: 302

Slide 33

Slide 33 text

class Integer # The bottles def drink; self - 1; end end class << song = nil attr_accessor :wall def bottles (@bottles.zero? ? "no more" : @bottles).to_s << " bottle" << ("s" unless @bottles == 1).to_s end def of(bottles) @bottles = bottles (class << self; self; end).module_eval do define_method(:buy) { bottles } end self end def sing(&step) puts "#{bottles.capitalize} of beer on the wall, #{bottles} of beer." if @bottles.zero? print "Go to the store buy some more, " step = method :buy else print "Take one down and pass it around, " end @bottles = step[@bottles] puts "#{bottles} of beer on the wall." puts "" or wall.call unless step.kind_of? Method end end callcc { |song.wall| song.of(99) }.sing { |beer| beer.drink }

Slide 34

Slide 34 text

Continuations sind ein nettes Instrument, um sich mal richtig schön verwirren zu lassen …sonst vermutlich eher weniger relevant in der Praxis Fibers sind durchaus nützlich (async APIs)

Slide 35

Slide 35 text

One More Thing …

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

✓Alle Getränke inklusive ✓Professionelle Reinigung ✓Hochwertige Büromöbel ✓100 Mbit Breitband-Internet ✓Nutzung von Drucker etc. ✓Erstklassiger Kaffee * inkl. 19% UmSt für pro Monat 359 € *

Slide 40

Slide 40 text

http://home-office-cologne.de @ HomeOfficeCGN

Slide 41

Slide 41 text

$keynote.call

Slide 42

Slide 42 text

Ruby #666 Black Magic

Slide 43

Slide 43 text

Kernel.throw :faq

Slide 44

Slide 44 text

Thanks! Q & A? Dirk Breuer / @railsbros_dirk Sebastian Cohnen / @tisba ? “My Little Pony” © Hasbro Studios and DHX Media Vancouver rubyismagic.de