module MethodDecorators
An implementation of pythonish decorators in Ruby Credits: Yehuda Katz (yehudakatz.com/) github.com/wycats/ruby_decorators
Attributes
decorated_methods[RW]
Public Class Methods
extended(klass)
click to toggle source
# File lib/performance_promise/decorators.rb, line 7 def self.extended(klass) class << klass attr_accessor :decorated_methods end end
Public Instance Methods
decorate(klass, *args)
click to toggle source
# File lib/performance_promise/decorators.rb, line 56 def decorate(klass, *args) @decorators ||= [] @decorators << [klass, args] end
method_added(name)
click to toggle source
# File lib/performance_promise/decorators.rb, line 31 def method_added(name) return unless @decorators decorators = @decorators.dup @decorators = nil @decorated_methods ||= Hash.new {|h,k| h[k] = []} class << self; attr_accessor :decorated_methods; end decorators.each do |klass, args| decorator = klass.respond_to?(:new) ? klass.new(self, instance_method(name), *args) : klass @decorated_methods[name] << decorator end class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 def #{name}(*args, &blk) ret = nil self.class.decorated_methods[#{name.inspect}].each do |decorator| ret = decorator.call(self, *args, &blk) end ret end ruby_eval end
method_missing(name, *args, &blk)
click to toggle source
Calls superclass method
# File lib/performance_promise/decorators.rb, line 13 def method_missing(name, *args, &blk) if Object.const_defined?(name) const = Object.const_get(name) elsif Decorator.decorators.key?(name) const = Decorator.decorators[name] else return super end instance_eval <<-ruby_eval, __FILE__, __LINE__ + 1 def #{name}(*args, &blk) decorate(#{const.name}, *args, &blk) end ruby_eval send(name, *args, &blk) end