Instantly share code, notes, and snippets.

@tisba /base_decorator.rb Secret
Created Jan 22, 2012

Embed
What would you like to do?
RIM007 - Python-style Decorators
class BaseDecorator
def initialize(closure)
@closure = closure
end
def bind_to(receiver)
@closure = @closure.bind(receiver)
end
end
class CacheDecorator < BaseDecorator
def call(*args)
puts "Before closure"
result = @closure.call(*args)
puts "After closure"
return result
end
end
module FunctionDecorators
def self.included(receiver)
receiver.instance_eval {
def decorate(decorator)
@decorate_next_with = decorator
end
def method_added(name)
if @decorate_next_with
FunctionDecorators.apply_decorator(@decorate_next_with, name, self)
@decorate_next_with = nil
end
end
def __decorators
@_decorators ||= {}
end
}
end
def self.apply_decorator(decorator, method_name, target)
decorated_method = target.instance_method(method_name)
target.send(:remove_method, method_name)
target.__decorators[method_name] = decorator.new(decorated_method)
new_method = <<-RUBY
def #{method_name}(#{params = decorated_method.parameters.collect(&:last).join(',')})
self.class.__decorators[:#{method_name}].bind_to(self)
self.class.__decorators[:#{method_name}].call(#{params})
end
RUBY
class_eval new_method
end
end
class Object
include FunctionDecorators
end
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
db_layer = DBLayer.new
db_layer.find(23)
puts db_layer.count
@tisba

This comment has been minimized.

Owner

tisba commented Jan 22, 2012

Beispiel Code zur Anwendung von Methoden als Closures aus der ersten Ausgabe von "Ruby is Magic" zum Thema Closures in Ruby: http://rubyismagic.de/blog/2012/01/19/episode-7-closures/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment