die zugewiesen und rumgereicht werden können. die jederzeit und von jedem aufgerufen werden können. die Zugriff auf Variablen im ursprünglich definierenden Kontext haben. Alle antworten auf call() Closures sind Codeblöcke, …
%w(MacBook Headphones iPhone Camera).each do |item| item_count ||= 0 @my_bag.add item item_count += 1 end puts "#{item_count} item(s) have been added to my bag." NameError: undefined local variable or method ‘item_count’
Werden an Methoden übergeben Fangen den definierenden Kontext ein Erweitern den definierenden Kontext nicht Können nicht herumgereicht oder jederzeit aufgerufen werden Blöcke
class Bag def initialize(items) @items = items end def each_item(&block) @items.each(&block) end end bag = Bag.new %w(MacBook Headphones Keys) bag.each_item { |item| puts item }
class Bag def initialize(items) @items = items end def define_iterator(&block) @iterator = block # Proc.new &block end def iterate! @items.each(&@iterator) end end bag = Bag.new(%w(MacBook Headphones Keys)) bag.define_iterator { |item| puts item } bag.iterate!
Kontrollfluss Proc.new ist abhängig von dem definierenden Kontext lambda verhält sich wie eine Methode (“true closure”) proc ist ein Alias auf lambda (Ruby 1.8) proc ist ein Alias auf Proc.new (Ruby 1.9)
LocalJumpError: unexpected return def call_closure(closure) puts "Calling a closure" result = closure.call puts "The result of the call was: #{result}" end call_closure(Proc.new { return "All hell breaks loose!" })
def cc(closure) puts "Calling a closure" result = closure.call puts "The result of the call was: '#{result}'" end cc(lambda { return "Everypony calm down. All is good." }) Calling a closure The result of the call was: ‘Everypony calm down. All is good.’
Fun facts In Ruby 1.8 lambda {||}.artiy != lambda {}.arity lambda {}.arity == -1 lambda checkt nicht die Argumente, wenn Arität 1 ist WTF!? In Ruby 1.9 lambda {}.arity == lambda {||}.arity == 0
class DBLayer decorate CacheDecorator def find(id) puts "Called :find with #{id}" puts "I am: #{self}" end def destroy; end def create; end decorate CacheDecorator def count puts "Called :count" return 1337 end end
Erkennen welche Methode zu dekorieren ist Methode extrahieren Decorator mit extrahierter Methode inititalisieren Proxy Methode definieren Binding vor Ausführung der “alten” Methode umsetzen Was müssen wir machen?