Module: Util::AddedMethods
Overview
Watch for added methods and record them. Inspired by unroller, <unroller.rubyforge.org/classes/Unroller.html#M000034>.
Example:
require 'rubygems'
require 'nuggets/util/added_methods/init'
require 'some/library/or/whatever'
matches = Util::AddedMethods.find(
:name => 'method_name',
:class => SomeClass # optional
)
# get the class(es) where matching method(s) were defined
matches.each { |am| puts am.klass # also am[:klass] or am[:class] }
# assume the first one is the one we're looking for
am = matches.first
# is it a singleton method?
puts am.singleton?
# where exactly has it been defined?
puts "#{am.file}, line #{am.line}"
# now get its source
puts am # implies #to_s, you can also call #extract_source directly
TODO:
-
multi-line statements in irb w/o ruby2ruby? (=> extract_source)
-
polishing!
Defined Under Namespace
Classes: AddedMethod
Constant Summary collapse
- HISTFILENAME =
'(Readline::HISTORY)'.freeze
Instance Method Summary collapse
- #all_methods ⇒ Object
- #callback(*args, &inner_block) ⇒ Object
- #callbacks ⇒ Object
- #define_callback(name, regexp = //, klasses = [], &outer_block) ⇒ Object
- #find(conditions = {}) ⇒ Object
- #find_by_class(*classes) ⇒ Object
- #find_by_name(*names) ⇒ Object
- #find_one_by_name_or_class(name_or_class, conditions = {}) ⇒ Object (also: #[])
- #init(regexp = nil, klasses = [], &block) ⇒ Object
- #install_callbacks(bases = [Object, Class, Module, Kernel]) ⇒ Object
- #remove_callback(name) ⇒ Object
- #replace_callback(name, regexp = nil, klasses = [], &outer_block) ⇒ Object
Instance Method Details
#all_methods ⇒ Object
246 247 248 249 |
# File 'lib/nuggets/util/added_methods.rb', line 246 def all_methods init_all_methods ALL_METHODS end |
#callback(*args, &inner_block) ⇒ Object
191 192 193 194 |
# File 'lib/nuggets/util/added_methods.rb', line 191 def callback(*args, &inner_block) callback_args = [identify_added_method(*args << caller), caller, inner_block] callbacks.each { |name, callback| callback[*callback_args] } end |
#callbacks ⇒ Object
186 187 188 189 |
# File 'lib/nuggets/util/added_methods.rb', line 186 def callbacks init_callbacks CALLBACKS end |
#define_callback(name, regexp = //, klasses = [], &outer_block) ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/nuggets/util/added_methods.rb', line 196 def define_callback(name, regexp = //, klasses = [], &outer_block) raise TypeError, "wrong argument type #{name.class} (expected Symbol)" unless name.is_a?(Symbol) raise "callback with name #{name} already exists" if callbacks.assoc(name) raise TypeError, "wrong argument type #{regexp.class} (expected Regexp)" unless regexp.is_a?(Regexp) raise TypeError, "wrong argument type #{klasses.class} (expected container object)" unless klasses.respond_to?(:empty?) && klasses.respond_to?(:include?) callbacks << [name, lambda { |am, callstack, inner_block| method, klass = am.name, am.klass return if %w[method_added singleton_method_added].include?(method) return unless klasses.empty? || klasses.include?(klass.to_s) return unless method =~ regexp if outer_block || inner_block outer_block[am] if outer_block inner_block[am] if inner_block else msg = "[#{am.base}] Adding #{'singleton ' if am.singleton?}method #{klass}##{method}" msg << if irb?(callstack) " in (irb:#{IRB.conf[:MAIN_CONTEXT].instance_variable_get(:@line_no)})" else " at #{where(callstack)}" end puts msg end }] end |
#find(conditions = {}) ⇒ Object
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/nuggets/util/added_methods.rb', line 251 def find(conditions = {}) conditions = conditions.dup class_condition = conditions.delete(:class) file_condition = conditions.delete(:file) results = [] all_methods.each { |klass, files| if class_condition next unless class_condition.is_a?(Array) ? class_condition.include?(klass) : klass == class_condition end files.each { |file, entries| if file_condition next unless file_condition.is_a?(Regexp) ? file =~ file_condition : file == file_condition end entries.each { |am| results << am if conditions.all? { |key, value| case value when Array, Range then value.include?(am[key]) when Regexp then value =~ am[key].to_s else value == am[key] end } } } } results end |
#find_by_class(*classes) ⇒ Object
284 285 286 287 |
# File 'lib/nuggets/util/added_methods.rb', line 284 def find_by_class(*classes) conditions = classes.last.is_a?(Hash) ? classes.pop : {} find(conditions.merge(:class => classes)) end |
#find_by_name(*names) ⇒ Object
289 290 291 292 |
# File 'lib/nuggets/util/added_methods.rb', line 289 def find_by_name(*names) conditions = names.last.is_a?(Hash) ? names.pop : {} find(conditions.merge(:name => names.map { |m| m.to_s })) end |
#find_one_by_name_or_class(name_or_class, conditions = {}) ⇒ Object Also known as: []
294 295 296 297 298 299 |
# File 'lib/nuggets/util/added_methods.rb', line 294 def find_one_by_name_or_class(name_or_class, conditions = {}) (name_or_class.is_a?(Class) ? find_by_class(name_or_class) : find_by_name(name_or_class) ).last end |
#init(regexp = nil, klasses = [], &block) ⇒ Object
178 179 180 181 182 183 184 |
# File 'lib/nuggets/util/added_methods.rb', line 178 def init(regexp = nil, klasses = [], &block) init_script_lines patch_readline_history define_callback(:__init, regexp, klasses, &block) if regexp install_callbacks end |
#install_callbacks(bases = [Object, Class, Module, Kernel]) ⇒ Object
237 238 239 240 241 242 243 244 |
# File 'lib/nuggets/util/added_methods.rb', line 237 def install_callbacks(bases = [Object, Class, Module, Kernel]) bases.each { |base| [base, singleton_class(base)].each { |b| b.send(:define_method, :method_added) { |id| AddedMethods.callback(b, self, id, false) } b.send(:define_method, :singleton_method_added) { |id| AddedMethods.callback(b, self, id, true) } } } end |
#remove_callback(name) ⇒ Object
228 229 230 |
# File 'lib/nuggets/util/added_methods.rb', line 228 def remove_callback(name) callbacks.delete_if { |n, _| n == name } end |
#replace_callback(name, regexp = nil, klasses = [], &outer_block) ⇒ Object
232 233 234 235 |
# File 'lib/nuggets/util/added_methods.rb', line 232 def replace_callback(name, regexp = nil, klasses = [], &outer_block) remove_callback(name) define_callback(name, regexp, klasses, &outer_block) end |