Skip to content

Instantly share code, notes, and snippets.

@tisba
Created January 22, 2012 21:33
Show Gist options
  • Select an option

  • Save tisba/294f56ed664efa99dcac to your computer and use it in GitHub Desktop.

Select an option

Save tisba/294f56ed664efa99dcac to your computer and use it in GitHub Desktop.
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
Copy link
Copy Markdown
Author

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