Module: Decorate
- Defined in:
- lib/decorate.rb,
lib/decorate/create_alias.rb
Defined Under Namespace
Modules: AroundDecorator, BeforeDecorator, Memoize, ModuleMethod, PrivateMethod, ProtectedMethod, PublicMethod Classes: BlockDecorator
Constant Summary collapse
- VERSION =
"0.3.0"
Class Method Summary collapse
-
.clear_decorators ⇒ Object
Clear the current threads decorator stack.
-
.create_alias(klass, method_name, id) ⇒ Object
Create a private alias for the instance method named
method_name
of classklass
. -
.decorate(decorator = nil, &block) ⇒ Object
Add a decorator that will be applied to the next method definition.
-
.process_decorators(klass, method_name) ⇒ Object
Apply the current threads decorator stack to the specified method.
-
.push_decorator(decorator) ⇒ Object
Push a decorator on the current threads decorator stack.
Class Method Details
.clear_decorators ⇒ Object
Clear the current threads decorator stack. Returns the old stack as an Enumerable.
29 30 31 32 33 |
# File 'lib/decorate.rb', line 29 def self.clear_decorators stack = (Thread.current[:_decorator_stack_] ||= []).dup Thread.current[:_decorator_stack_].clear stack end |
.create_alias(klass, method_name, id) ⇒ Object
Create a private alias for the instance method named method_name
of class klass
. The string representation of id
will be part of the alias to ease debugging. This method makes sure that the alias doesn’t redefine an existing method.
Returns the name of the new alias.
In the simplest case, the alias will be "#{method_name}without#{id}"
.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/decorate/create_alias.rb', line 12 def self.create_alias(klass, method_name, id) basename = "#{method_name}_without_#{id}" i = 0 new_name = basename loop { break unless klass.method_defined?(new_name) i += 1 new_name = "#{basename}_#{i}" } klass.send(:alias_method, new_name, method_name) klass.send(:private, new_name) new_name end |
.decorate(decorator = nil, &block) ⇒ Object
Add a decorator that will be applied to the next method definition. Either pass an object that responds to decorate(klass, method_name) or a block. The block will be wrapped in a BlockDecorator.
Example:
def trace_def
Decorate.decorate { |klass, method_name|
puts "Method #{method_name.inspect} defined in #{klass.inspect}"
}
end
class Foo
trace_def
def
# ...
end
end
# prints: Method :bar defined in Foo
55 56 57 58 59 60 61 62 63 |
# File 'lib/decorate.rb', line 55 def self.decorate(decorator = nil, &block) if decorator.nil? raise "decorator argument or block required" if block.nil? decorator = BlockDecorator.new(block) elsif block raise "won't accept block if decorator argument is given" end push_decorator(decorator) end |
.process_decorators(klass, method_name) ⇒ Object
Apply the current threads decorator stack to the specified method.
Decorate hooks into Module#method_added and Object#singleton_method_added to call this method.
69 70 71 72 73 |
# File 'lib/decorate.rb', line 69 def self.process_decorators(klass, method_name) Decorate.clear_decorators.reverse!.each { |decorator| decorator.decorate(klass, method_name) } end |
.push_decorator(decorator) ⇒ Object
Push a decorator on the current threads decorator stack. A decorator is an object that responds to decorate
taking a class and a method name (symbol) as arguments.
22 23 24 25 |
# File 'lib/decorate.rb', line 22 def self.push_decorator(decorator) raise TypeError, "#{decorator} not a decorator" unless decorator (Thread.current[:_decorator_stack_] ||= []).push(decorator) end |