Module: Aspect4r::Helper
- Defined in:
- lib/aspect4r/helper.rb
Constant Summary collapse
- METHOD_TEMPLATE =
method before_advices after_advices
ERB.new <<-CODE, nil, '<>' <% if inner_most %> wrapped_method = a4r_data.wrapped_methods['<%= method %>'] <% else %> wrapped_method = instance_method(:<%= method %>) <% end %> define_method :<%= method %> do |*args, &block| result = nil # Before advices <% before_advices.each do |definition| %> <% if definition.options[:method_name_arg] %> result = <%= definition.with_method %> '<%= method %>', *args <% else %> result = <%= definition.with_method %> *args <% end %> return result.value if result.is_a? ReturnThis <% if definition.options[:skip_if_false] %> return unless result <% end %> <% end %> <% if around_advice %> # around advice <% if around_advice.options[:method_name_arg] %> result = <%= around_advice.with_method %> '<%= method %>', *args do |*args| wrapped_method.bind(self).call *args, &block end <% else %> result = <%= around_advice.with_method %> *args do |*args| wrapped_method.bind(self).call *args, &block end <% end %> <% else %> # Invoke wrapped method result = wrapped_method.bind(self).call *args, &block <% end %> # After advices <% after_advices.each do |definition| %> <% if definition.options[:method_name_arg] and definition.options[:result_arg] %> result = <%= definition.with_method %> '<%= method %>', result, *args <% elsif definition.options[:method_name_arg] %> <%= definition.with_method %> '<%= method %>', *args <% elsif definition.options[:result_arg] %> result = <%= definition.with_method %> result, *args <% else %> <%= definition.with_method %> *args <% end %> <% end %> result end CODE
Class Method Summary collapse
-
.create_method(klass, method) ⇒ Object
method - target method.
- .create_method_with_advices(klass, method, advices, inner_most) ⇒ Object
- .creating_method? ⇒ Boolean
- .define_method(klass_or_module, *args, &block) ⇒ Object
- .find_available_method_name(klass, method_name_prefix) ⇒ Object
-
.process_advice(meta_data, klass_or_module, *methods, &block) ⇒ Object
Store original method in aspect data and refer to it whenever recreating method.
Class Method Details
.create_method(klass, method) ⇒ Object
method - target method
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/aspect4r/helper.rb', line 67 def self.create_method klass, method @creating_method = true advices = klass.a4r_data.advices_for_method method return if advices.empty? grouped_advices = [] group = nil inner_most = true advices.each do |advice| if ((group and group != advice.group) or advice.around?) and not grouped_advices.empty? create_method_with_advices klass, method, grouped_advices, inner_most grouped_advices = [] inner_most = false end grouped_advices << advice group = advice.group end # create wrap method for before/after advices which are not wrapped inside around advice. create_method_with_advices klass, method, grouped_advices, inner_most unless grouped_advices.empty? ensure @creating_method = nil end |
.create_method_with_advices(klass, method, advices, inner_most) ⇒ Object
155 156 157 158 159 160 161 162 163 |
# File 'lib/aspect4r/helper.rb', line 155 def self.create_method_with_advices klass, method, advices, inner_most before_advices = advices.select {|advice| advice.before? or advice.before_filter? } after_advices = advices.select {|advice| advice.after? } around_advice = advices.first if advices.first.around? code = METHOD_TEMPLATE.result(binding) # puts code klass.class_eval code, __FILE__ end |
.creating_method? ⇒ Boolean
12 13 14 |
# File 'lib/aspect4r/helper.rb', line 12 def self.creating_method? @creating_method end |
.define_method(klass_or_module, *args, &block) ⇒ Object
16 17 18 19 20 21 |
# File 'lib/aspect4r/helper.rb', line 16 def self.define_method klass_or_module, *args, &block @creating_method = true klass_or_module.send :define_method, *args, &block ensure @creating_method = false end |
.find_available_method_name(klass, method_name_prefix) ⇒ Object
5 6 7 8 9 10 |
# File 'lib/aspect4r/helper.rb', line 5 def self.find_available_method_name klass, method_name_prefix 0.upto(10000) do |i| m = "#{method_name_prefix}#{i}_#{klass.hash}" return m unless klass.private_instance_methods(false).include?(m) end end |
.process_advice(meta_data, klass_or_module, *methods, &block) ⇒ Object
Store original method in aspect data and refer to it whenever recreating method
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/aspect4r/helper.rb', line 24 def self.process_advice , klass_or_module, *methods, &block methods.flatten! = ..clone .merge!(methods.pop) if methods.last.is_a? Hash .merge!(.) # Convert symbols to strings to avoid inconsistencies methods.size.times do |i| methods[i] = methods[i].to_s if methods[i].is_a? Symbol end if block_given? with_method = find_available_method_name klass_or_module, .with_method_prefix klass_or_module.send :define_method, with_method, &block klass_or_module.send :private, with_method else with_method = methods.pop end a4r_data = klass_or_module.a4r_data advice = Aspect4r::Model::Advice.new(.advice_type, Aspect4r::Model::MethodMatcher.new(*methods), with_method, a4r_data.group, ) a4r_data << advice methods.each do |method| next unless method.is_a? String wrapped_method = a4r_data.wrapped_methods[method] if not wrapped_method and klass_or_module.instance_methods.include?(method) wrapped_method = klass_or_module.instance_method(method) a4r_data.wrapped_methods[method] = wrapped_method end create_method klass_or_module, method if wrapped_method end end |