Class: Module
Overview
Source from www.erikveen.dds.nl/monitorfunctions/index.html
Instance Method Summary collapse
- #post_condition(*method_names, &block1) ⇒ Object
- #pre_and_post_condition(pre, post, *method_names, &block1) ⇒ Object
-
#pre_condition(*method_names, &block1) ⇒ Object
Since adding code at the beginning or at the end of an instance method is very common, we simplify this by providing the next methods.
-
#wrap_method(*method_names, &block1) ⇒ Object
This wrap_method is low-level stuff.
-
#wrap_module_method(*method_names, &block1) ⇒ Object
Deprecated.
Instance Method Details
#post_condition(*method_names, &block1) ⇒ Object
135 136 137 |
# File 'lib/wrap_method.rb', line 135 def post_condition(*method_names, &block1) pre_and_post_condition(false, true, *method_names, &block1) end |
#pre_and_post_condition(pre, post, *method_names, &block1) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/wrap_method.rb', line 139 def pre_and_post_condition(pre, post, *method_names, &block1) method_names.flatten.each do |method_name| wrap_method(method_name) do |org_method, args2, block2, obj2| block1.call(obj2, method_name, args2, block2) if pre res = org_method.call(*args2, &block2) if org_method block1.call(obj2, method_name, args2, block2) if post res end end end |
#pre_condition(*method_names, &block1) ⇒ Object
Since adding code at the beginning or at the end of an instance method is very common, we simplify this by providing the next methods. Althoug they’re named *_condition, they’re not checking anything. They should be named *_action. But pre_action is harder to remember than pre_condition. So I stick to the latter.
131 132 133 |
# File 'lib/wrap_method.rb', line 131 def pre_condition(*method_names, &block1) pre_and_post_condition(true, false, *method_names, &block1) end |
#wrap_method(*method_names, &block1) ⇒ Object
This wrap_method is low-level stuff. If you just want to add code to a method, scroll down to pre_condition and post_condition. They’re much easier to use.
23 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 65 66 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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/wrap_method.rb', line 23 def wrap_method(*method_names, &block1) raise ArgumentError, "method_name is missing" if method_names.empty? raise ArgumentError, "block is missing" unless block1 Thread.exclusive do method_names.flatten.each do |method_name| count = Module.module_eval do @_wm_count_ ||= 0 @_wm_count_ +=1 end module_eval <<-EOF # Get the method which is to be wrapped. method = instance_method(:"#{method_name}") rescue nil # But it shouldn't be defined in a super class... if method.to_s != "#<UnboundMethod: " + self.to_s + "##{method_name}>" method = nil end if method.nil? and ($VERBOSE or $DEBUG) $stderr.puts \ "Wrapping a non-existing method ["+self.to_s+"##{method_name}]." end # Store the method-to-be-wrapped and the wrapping block. define_method(:"_wm_previous_#{method_name}_#{count}_") do [method, block1] end # Avoid this stupid "warning: method redefined". unless :#{method_name} == :initialize undef_method(:"#{method_name}") rescue nil end # Define __class__ and __kind_of__. define_method(:__class__) \ {Object.instance_method(:class).bind(self).call} define_method(:__kind_of__) \ {|s| Object.instance_method(:"kind_of?").bind(self).call(s)} # Define the new method. def #{method_name}(*args2, &block2) if self.__kind_of__(Module) context = metaclass else context = self.__class__ end # Retrieve the previously stored method-to-be-wrapped (old), # as well as the wrapping block (new). # Note: An UnboundMethod of self.superclass.metaclass can't be # bound to self.metaclass, so we "walk up" the class hierarchy. previous = context.instance_method( :"_wm_previous_#{method_name}_#{count}_") begin previous = previous.bind(zelf ||= self) rescue TypeError => e retry if zelf = zelf.superclass end old, new = previous.call # If there's no method-to-be-wrapped in the current class, we # should look for it in the superclass. old ||= context.superclass.instance_method(:"#{method_name}") rescue nil # Since old is an unbound method, we should bind it. # Note: An UnboundMethod of self.superclass.metaclass can't be # bound to self.metaclass, so we "walk up" the class hierarchy. begin old &&= old.bind(zelf ||= self) rescue TypeError => e retry if zelf = zelf.superclass end # Finally... new.call(old, args2, block2, self) end EOF end end end |
#wrap_module_method(*method_names, &block1) ⇒ Object
Deprecated
115 116 117 118 119 120 121 122 |
# File 'lib/wrap_method.rb', line 115 def wrap_module_method(*method_names, &block1) # Deprecated if $VERBOSE or $DEBUG $stderr.puts "Module#wrap_module_method is deprecated." $stderr.puts "Use aModule.metaclass.wrap_method instead." end .wrap_method(*method_names, &block1) end |