Slide 1

Slide 1 text

Brony User Group Cologne hosted by 18.7.2012

Slide 2

Slide 2 text

Ruby #138 Spectacular

Slide 3

Slide 3 text

“Hold on to your hooves, I'm about to be BRILLIANT!” – Pinkie Pie

Slide 4

Slide 4 text

undef_method

Slide 5

Slide 5 text

Configuration DSL App.configure do |config| redis do host "127.0.0.1" port 6379 end amqp do host "127.0.0.1" port 5672 auto_recovery true timeout 1 logging true end end

Slide 6

Slide 6 text

ArgumentError: wrong number of arguments (0 for 1) ! from …/lib/ruby/1.9.1/timeout.rb:98:in `timeout' ! from … App.config[:amqp][:timeout]

Slide 7

Slide 7 text

What in tarnation?!

Slide 8

Slide 8 text

# File: timeout.rb module Timeout def timeout(sec, klass = nil) #:yield: +sec+ # Implementation of the timeout functionality end module_function :timeout end # Identical to: # # Timeout::timeout(n, e, &block). # # This method is deprecated and provided only for backwards compatibility. # You should use Timeout#timeout instead. def timeout(n, e = nil, &block) Timeout::timeout(n, e, &block) end Global Namespace Pollution!

Slide 9

Slide 9 text

class App class Configuration < Hash undef_method(:timeout) def initialize(&block) super() instance_eval &block end def method_missing(meth, *subjects, &block) # Fancy method_missing action for DSL end end def self.configure(&block) @config = App::Configuration.new(block) end end

Slide 10

Slide 10 text

App.config[:amqp][:timeout] # => 1

Slide 11

Slide 11 text

method(:method_name)

Slide 12

Slide 12 text

Callbacks bei asynchroner Ausführung class AmqpClient def connect(options = {}) @connection = AMQP.connect(options) { |connection| … } @connection.on_tcp_connection_loss do |connection, settings| # Handle connection loss end @connection.on_recovery do |connection, settings| # Handle connection recovery end end def publish(message); end end

Slide 13

Slide 13 text

Probleme? Callbacks in Blockform sind sehr schwer zu testen Sehr große initialize-Methode Dokumentation der Callbacks umständlich Callbacks nur implizit

Slide 14

Slide 14 text

method to the rescue

Slide 15

Slide 15 text

class AmqpClient def connect(options = {}) @connection.on_tcp_connection_loss &method(:on_tcp_connection_loss) @connection.on_recovery &method(:on_recovery) end def on_tcp_connection_loss(connection, settings) # Handle connection loss end def on_recovery(connection, settings) # Handle connection recovery end end

Slide 16

Slide 16 text

Callbacks einzeln und in Isolation testbar initialize-Method übersichtlicher Dokumentation der Callbacks über RDoc etc. möglich Callbacks sind explizit gemacht

Slide 17

Slide 17 text

Ruby is Magic ist nicht immer sinnlos In manchen Fällen kann es Code verbessern Immer abzuwägen wie viele und wer den Code noch lesen muss

Slide 18

Slide 18 text

One More Thing …

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

Binding

Slide 21

Slide 21 text

Kapseln den Ausführungskontext Erhalten Zugriff auf Variablen, Methoden, self Werden erzeugt mit Kernel#binding

Slide 22

Slide 22 text

class Pony def say_hello(a_binding = nil) eval('puts "Hello, my name is #{@name}"', a_binding || binding) end end somepony = Pony.new somepony.say_hello # Hello, my name is @name = "Rainbow Dash" somepony.say_hello(binding) # Hello, my name is Rainbow Dash @name = "Applejack" somepony.say_hello(binding) # Hello, my name is Applejack

Slide 23

Slide 23 text

Okay …

Slide 24

Slide 24 text

… ERB!

Slide 25

Slide 25 text

require 'erb' class View def friend "Pinkie Pie" end def get_binding binding end end template = ERB.new <<-ERB Welcome to Ruby is Magic! Let me introduce you to my good friend <%= friend %>. ERB puts template.result # (erb):3:in `': undefined local variable or method `friend' for main:Object # from /lib/ruby/1.9.1/erb.rb:838:in `eval' # from /lib/ruby/1.9.1/erb.rb:838:in `result' # from Ruby is Magic.rb/011-clip-show/code/erb_demo.rb:19:in `' puts template.result(View.new.get_binding) # Let me introduce you to my good friend Pinkie Pie.

Slide 26

Slide 26 text

Giveaway

Slide 27

Slide 27 text

autocmd FileType ruby compiler ruby function Run() let executable=b:current_compiler if !getbufvar("%", "&saved") let tmpfile = tempname() silent! exe "write " . tmpfile . ".rb" endif let filename=expand('%:p') " Create the previewwindow if doesn't exist if ! &previewwindow pedit /tmp/_vim_previewwindow endif " Change to the previewwindow silent! wincmd P " Run the file with and switch back to the previous window execute "%d|silent 0r!" . executable . " '" . filename . "'" wincmd p endfunction map r :call Run()

Slide 28

Slide 28 text

https://gist.github.com/3137064

Slide 29

Slide 29 text

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