class Aquarium::Aspects::AdviceChainNode

Supports Enumerable, but not the sorting methods, as this class is a linked list structure. This is of limited usefulness, because you wouldn’t use an iterator to invoke the procs in the chain, because each proc will invoke the next node arbitrarily or possibly not at all in the case of around advice!

Constants

NIL_OBJECT

TODO: remove this method, which causes run-away recursions in R1.9.1 def inspect &block

block ? yield(self) : super

end

Public Class Methods

new(options = {}) click to toggle source
# File lib/aquarium/aspects/advice.rb, line 47
      def initialize options = {}
        # assign :next_node and :static_join_point so the attributes are always created
        options[:next_node] ||= nil  
        options[:static_join_point] ||= nil
        options.each do |key, value|
          instance_variable_set "@#{key}".intern, value
          (class << self; self; end).class_eval("            attr_accessor(:#{key})
", __FILE__, __LINE__)
        end
      end

Public Instance Methods

call(jp) click to toggle source
# File lib/aquarium/aspects/advice.rb, line 68
def call jp
  begin
    advice_wrapper jp
  rescue Exception => e
    handle_call_rescue e, "", jp
  end
end
call_advice(jp) click to toggle source

Bug #19262 workaround: need to only pass jp argument if arity is 1.

# File lib/aquarium/aspects/advice.rb, line 60
def call_advice jp
  if advice.arity == 1
    advice.call jp
  else
    advice.call jp, jp.context.advised_object, *jp.context.parameters
  end
end
each() { |node| ... } click to toggle source

Supports Enumerable

# File lib/aquarium/aspects/advice.rb, line 85
def each 
  node = self 
  while node.nil? == false 
    yield node 
    node = node.next_node 
  end 
end
empty?() click to toggle source
# File lib/aquarium/aspects/advice.rb, line 103
def empty?
  next_node.nil?
end
invoke_original_join_point(current_jp) click to toggle source
# File lib/aquarium/aspects/advice.rb, line 76
def invoke_original_join_point current_jp
  begin
    last.advice_wrapper current_jp
  rescue Exception => e
    handle_call_rescue e, "While executing the original join_point: ", current_jp
  end
end
last() click to toggle source
# File lib/aquarium/aspects/advice.rb, line 93
def last
  last_node = nil
  each { |node| last_node = node unless node.nil? } 
  last_node
end
size() click to toggle source
# File lib/aquarium/aspects/advice.rb, line 99
def size
  inject(0) {|memo, node| memo += 1}
end

Protected Instance Methods

handle_call_rescue(ex, error_message_prefix, jp) click to toggle source
# File lib/aquarium/aspects/advice.rb, line 133
def handle_call_rescue ex, error_message_prefix, jp
  if Aquarium::Aspects::Advice.debug_backtraces
    class_or_instance_method_separater = jp.instance_method? ? "#" : "."
    context_message = error_message_prefix + "Exception raised while executing \"#{jp.context.advice_kind}\" advice for \"#{jp.type_or_object.inspect}#{class_or_instance_method_separater}#{jp.method_name}\": "

    # Don't prepend the same context message multiple times
    if ex.message =~ /#{context_message}/
      context_message = ""
    end

    backtrace = ex.backtrace
    e2 = ex.exception(context_message + ex.message + " (join_point = #{jp.inspect})")
    e2.set_backtrace backtrace
    raise e2
  else
    raise ex
  end
end
reset_current_context(jp) click to toggle source
# File lib/aquarium/aspects/advice.rb, line 127
def reset_current_context jp 
  return if advice.arity == 0
  jp.context.advice_kind = @last_advice_kind
  jp.context.current_advice_node = @last_advice_node
end
update_current_context(jp) click to toggle source
# File lib/aquarium/aspects/advice.rb, line 120
def update_current_context jp
  return if advice.arity == 0
  @last_advice_kind = jp.context.advice_kind
  @last_advice_node = jp.context.current_advice_node
  jp.context.current_advice_node = self
end