module Orientdb4r::Aop2::ClassMethods2

Attributes

hooks[R]

Public Instance Methods

add_hook(type, original_method, *hooks) click to toggle source
# File lib/orientdb4r/utils.rb, line 142
def add_hook(type, original_method, *hooks) #!!
  Array(original_method).each do |method|
    store_hook(type, method, *hooks)
  end
end
after(original_method, *hooks) click to toggle source
# File lib/orientdb4r/utils.rb, line 134
def after(original_method, *hooks)
  add_hook(:after, original_method, *hooks)
end
around(original_method, *hooks) click to toggle source
# File lib/orientdb4r/utils.rb, line 137
def around(original_method, *hooks)
  add_hook(:around, original_method, *hooks)
end
before(original_method, *hooks) click to toggle source
# File lib/orientdb4r/utils.rb, line 131
def before(original_method, *hooks)
  add_hook(:before, original_method, *hooks)
end
init_aop_extension() click to toggle source
# File lib/orientdb4r/utils.rb, line 106
def init_aop_extension
  @hooks = {}
  [:before, :after, :around].each { |where| @hooks[where] = Hash.new { |hash, key| hash[key] = [] }}
  # will be like this:
  # {:before=>{:disconnect=>[:assert_connected], :query=>[:assert_connected], :command=>[:assert_connected]}, :after=>{}, :around=>{}}
  class << self
    attr_reader :hooks
  end
  @@redefining = false # flag whether the process of method redefining is running
end
invoke_arround_hooks(obj, method_name, hooks, &block) click to toggle source
# File lib/orientdb4r/utils.rb, line 192
def invoke_arround_hooks(obj, method_name, hooks, &block)
  hook = hooks.slice! 0
  return block.call if hook.nil? # call original method if no more hook

  # invoke the hook with lambda containing recursion
  obj.send(hook.to_sym) { invoke_arround_hooks(obj, method_name, hooks, &block); }
end
invoke_hooks(obj, hook_type, method_name) click to toggle source
# File lib/orientdb4r/utils.rb, line 189
def invoke_hooks(obj, hook_type, method_name)
  hooks[hook_type][method_name.to_sym].each { |hook| obj.send hook }
end
is_hooked?(method) click to toggle source
# File lib/orientdb4r/utils.rb, line 124
def is_hooked?(method)
  # look into array of keys (method names) in 2nd level hashs (see above)
  hooks.values.map(&:keys).flatten.uniq.include? method
end
method_added(method) click to toggle source
# File lib/orientdb4r/utils.rb, line 116
def method_added(method)
  unless @@redefining # avoid recursion
    redefine_method(method) if is_hooked?(method)
  end
end
redefine_method(orig_method) click to toggle source
# File lib/orientdb4r/utils.rb, line 151
      def redefine_method(orig_method)
        @@redefining = true

        arity = instance_method(orig_method.to_sym).arity
        params = ''
        fixed_cnt = arity.abs
        fixed_cnt -= 1 if arity < 0
        # build up a list of params
        1.upto(fixed_cnt).each {|x| params << "p#{x},"}
        params << "*argv" if arity < 0
        params.gsub!(/,$/, '') # remove last ','

        alias_method "#{orig_method}_aop2_orig".to_sym, orig_method.to_sym

        class_eval <<-FILTER,__FILE__,__LINE__ + 1
          def #{orig_method}(#{params})
            self.aop_context = { :method => '#{orig_method}', :class => self.class }
            begin
              self.class.invoke_hooks(self, :before, :#{orig_method})
              rslt = self.class.invoke_arround_hooks(self, :#{orig_method}, self.class.hooks[:around][:#{orig_method}].clone) {
                #{orig_method}_aop2_orig(#{params})
              }
              self.class.invoke_hooks(self, :after, :#{orig_method})
#            rescue Exception => e
#              # TODO use logging
#              $stderr.puts '' << e.class.name << ': ' << e.message
#              $stderr.puts e.backtrace.inspect
#              raise e
            ensure
              self.aop_context = nil
            end
            rslt
          end
        FILTER

        @@redefining = false
      end
store_hook(type, method_name, *hook_methods) click to toggle source
# File lib/orientdb4r/utils.rb, line 147
def store_hook(type, method_name, *hook_methods) #!!
  hooks[type.to_sym][method_name.to_sym] += hook_methods.flatten.map(&:to_sym)
end