Module: Innate::Helper::Aspect
- Defined in:
- /home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/helper/aspect.rb
Overview
The Aspect helper allows you to execute hooks before or after a number of actions.
See SingletonMethods for more details on the various hooks available.
This helper is essential for proper working of Action#render.
Defined Under Namespace
Modules: SingletonMethods
Constant Summary
- AOP =
Hash containing the various hooks to call for certain actions.
Hash.new { |h,k| h[k] = Hash.new { |hh,kk| hh[kk] = {} } }
Class Method Summary (collapse)
-
+ (Object) ancestral_aop(from)
Consider objects that have Aspect included.
-
+ (Object) included(into)
Called whenever this helper is included into a class.
Instance Method Summary (collapse)
-
- (Object) aspect_call(position, name)
Calls the aspect for a given position and name.
-
- (Object) aspect_wrap(action)
Wraps the specified action between various hooks.
-
- (Object) wrap_action_call(action, &block)
This awesome piece of hackery implements action AOP.
Class Method Details
+ (Object) ancestral_aop(from)
Consider objects that have Aspect included
49 50 51 52 53 54 55 56 57 |
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/helper/aspect.rb', line 49 def self.ancestral_aop(from) aop = {} from.ancestors.reverse.each do |anc| aop.merge!(AOP[anc]) if anc < Aspect end aop end |
+ (Object) included(into)
Called whenever this helper is included into a class.
43 44 45 46 |
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/helper/aspect.rb', line 43 def self.included(into) into.extend(SingletonMethods) into.add_action_wrapper(5.0, :aspect_wrap) end |
Instance Method Details
- (Object) aspect_call(position, name)
Calls the aspect for a given position and name.
65 66 67 68 69 70 71 72 |
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/helper/aspect.rb', line 65 def aspect_call(position, name) return unless aop = Aspect.ancestral_aop(self.class) return unless block = at_position = aop[position] block = at_position[name.to_sym] unless at_position.is_a?(Proc) instance_eval(&block) if block end |
- (Object) aspect_wrap(action)
Wraps the specified action between various hooks.
79 80 81 82 83 84 85 86 87 88 89 |
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/helper/aspect.rb', line 79 def aspect_wrap(action) return yield unless method = action.name aspect_call(:before_all, method) aspect_call(:before, method) result = yield aspect_call(:after, method) aspect_call(:after_all, method) result end |
- (Object) wrap_action_call(action, &block)
This awesome piece of hackery implements action AOP.
The so-called aspects are simply methods that may yield the next aspect in the chain, this is similar to racks concept of middleware, but instead of initializing with an app we simply pass a block that may be yielded with the action being processed.
This gives us things like logging, caching, aspects, authentication, etc.
Add the name of your method to the trait[:wrap] to add your own method to the wrap_action_call chain.
methods may register themself in the trait[:wrap] and will be called in left-to-right order, each being passed the action instance and a block that they have to yield to continue the chain.
131 132 133 134 135 136 137 138 139 |
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/helper/aspect.rb', line 131 def wrap_action_call(action, &block) return yield if action.[:is_layout] wrap = SortedSet.new action.node.ancestral_trait_values(:wrap).each{|sset| wrap.merge(sset) } head, *tail = wrap.map{|k,v| v } tail.reverse! combined = tail.inject(block){|s,v| lambda{ __send__(v, action, &s) } } __send__(head, action, &combined) end |