This class monitors method calls before and after. It simply reroutes the responsibility to the appropriate pluggable type system which does the actual work of gathering type information.
This method returns the alternative (renamed) method name
# File lib/rubybreaker/runtime/monitor.rb, line 146 def self.get_alt_meth_name(meth_name) return "__rubybreaker_#{meth_name}" end
This method returns the original method name
# File lib/rubybreaker/runtime/monitor.rb, line 151 def self.get_orig_meth_name(meth_name) return meth_name[2..-1] end
# File lib/rubybreaker/runtime/monitor.rb, line 155 def initialize(pluggable) @pluggable = pluggable end
This will do the actual routing work for a particular “monitored” method call.
:break or :check
is the object receiving the message; is never wrapped object
is a
is the block
argument for the original method call
# File lib/rubybreaker/runtime/monitor.rb, line 47 def self.route(route_type, obj, meth_name, *args, &blk) # remember the switch mode before turning it off switch = GLOBAL_MONITOR_SWITCH.switch # turn off the monitor so we do not fall into an infinite loop GLOBAL_MONITOR_SWITCH.turn_off() # use symbol instead of string throughout this code meth_name = :"#{meth_name}" # first, get the context right # notice the argument 2 to the caller! # # CONTEXT.push(obj, meth_name, # Position.convert_caller_to_pos(caller(2))) CONTEXT.push(Position.convert_caller_to_pos(caller(2))) # this is what the renamed method stub_meth_name = get_alt_meth_name(meth_name) RubyBreaker.log("Route to #{stub_meth_name}", :debug, CONTEXT) # short-circuit if switch was off--i.e., no monitoring if !switch retval = obj.send(stub_meth_name.to_sym,*args,&blk) CONTEXT.pop() # do not forget to pop the context before returning return retval end is_obj_mod = (obj.class == Class or obj.class == Module) mod = is_obj_mod ? Runtime.eigen_class(obj) : obj.class # mm = get_module_monitor(mod) unless is_obj_mod mm = MONITOR_MAP[mod] # There is something wrong if there isn't a module monitor # associated with the call. # raise Exception if mm == nil || !mm.include?(meth_name) meth_info = MethodInfo.new(meth_name, args, blk, nil) begin case route_type when :break mm.break_before_method(obj, meth_info) when :check mm.check_before_method(obj, meth_info) end rescue ::Exception => e RubyBreaker.log("Exception #{e.class} has been raised.", :debug, CONTEXT) # Trap it, turn on the global monitor and then re-raise the # exception GLOBAL_MONITOR_SWITCH.turn_on() raise e end # we are going to turn the switch back on GLOBAL_MONITOR_SWITCH.turn_on() # call the original method which was renamed retval = obj.send(stub_meth_name.to_sym, *meth_info.args, &meth_info.blk) # turn the switch off again GLOBAL_MONITOR_SWITCH.turn_off() # Remember the return value in the method info object. meth_info.ret = retval begin case route_type when :break mm.break_after_method(obj, meth_info) when :check mm.check_after_method(obj, meth_info) end rescue ::Exception => e # Trap it, turn on the global monitor and then re-raise the # exception RubyBreaker.log("Exception #{e.class} has been raised.", :debug, CONTEXT) GLOBAL_MONITOR_SWITCH.turn_on() raise e end retval = meth_info.ret # Return value may have been altered by the # after_method monitoring code # things are done in this context. pop it off. CONTEXT.pop() # it is always the case that the switch was off when this particular # call was made. (Otherwise, it would have quit somewhere above GLOBAL_MONITOR_SWITCH.turn_on() return retval # always return the return value end
This method is invoked after the original method is executed.
# File lib/rubybreaker/runtime/monitor.rb, line 175 def break_after_method(obj, meth_info) @pluggable.break_after_method(obj, meth_info) end
This method is invoked before the original method is executed.
# File lib/rubybreaker/runtime/monitor.rb, line 170 def break_before_method(obj, meth_info) @pluggable.break_before_method(obj, meth_info) end
This method is invoked after the original method is executed.
# File lib/rubybreaker/runtime/monitor.rb, line 165 def check_after_method(obj, meth_info) @pluggable.check_after_method(obj, meth_info) end
This method is invoked before the original method is executed.
# File lib/rubybreaker/runtime/monitor.rb, line 160 def check_before_method(obj, meth_info) @pluggable.check_before_method(obj, meth_info) end