Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby is Magic: Black Magic

Ruby is Magic: Black Magic

This time @tisba and I talked about some more or less esoteric features of Ruby like Continuations. As usual the talk is in German, because we gave it at the Cologne Ruby usergroup (Cologne.rb).

Copyright Notice: My Little Pony - Friendship is Magic is Property of Hasbro and The Hub.

Dirk Breuer

May 15, 2013
Tweet

More Decks by Dirk Breuer

Other Decks in Programming

Transcript

  1. 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
  2. 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 `<main>'"] # bar: ["cont_stack.rb:7:in `foo'", "cont_stack.rb:21:in `<main>'"] # counter: 0 # bar: ["cont_stack.rb:7:in `foo'", "cont_stack.rb:21:in `<main>'"] # counter: 1 # callme: ["cont_stack.rb:25:in `<main>'"]
  3. 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
  4. 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
  5. @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 `<main>'"] # 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 `<main>'"] # callme: ["fiber_stack.rb:37:in `<main>'"] # callme after foo: ["fiber_stack.rb:37:in `<main>'"] # counter: 0
  6. sequence = Enumerator.new do |yielder| number = 0 loop do

    number += 1 yielder.yield number end end Fiber!
  7. 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
  8. 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 }
  9. 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)
  10. ✓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 € *
  11. Thanks! Q & A? Dirk Breuer / @railsbros_dirk Sebastian Cohnen

    / @tisba ? “My Little Pony” © Hasbro Studios and DHX Media Vancouver rubyismagic.de