module AddedMethods

TODO:

Constants

HISTFILENAME
VERSION

Public Instance Methods

[](name_or_class, conditions = {})
all_methods() click to toggle source
    # File lib/added_methods.rb
113 def all_methods
114   init_all_methods
115   ALL_METHODS
116 end
callback(*args, &inner_block) click to toggle source
   # File lib/added_methods.rb
58 def callback(*args, &inner_block)
59   callback_args = [identify_added_method(*args << caller), caller, inner_block]
60   callbacks.each { |name, callback| callback[*callback_args] }
61 end
callbacks() click to toggle source
   # File lib/added_methods.rb
53 def callbacks
54   init_callbacks
55   CALLBACKS
56 end
define_callback(name, regexp = //, klasses = [], &outer_block) click to toggle source
   # File lib/added_methods.rb
63 def define_callback(name, regexp = //, klasses = [], &outer_block)
64   raise TypeError, "wrong argument type #{name.class} (expected Symbol)" unless name.is_a?(Symbol)
65   raise "callback with name #{name} already exists" if callbacks.assoc(name)
66 
67   raise TypeError, "wrong argument type #{regexp.class} (expected Regexp)" unless regexp.is_a?(Regexp)
68   raise TypeError, "wrong argument type #{klasses.class} (expected container object)" unless klasses.respond_to?(:empty?) && klasses.respond_to?(:include?)
69 
70   callbacks << [name, lambda { |am, callstack, inner_block|
71     method, klass = am.name, am.klass
72 
73     return if %w[method_added singleton_method_added].include?(method)
74 
75     return unless klasses.empty? || klasses.include?(klass.to_s)
76     return unless method =~ regexp
77 
78     if outer_block || inner_block
79       outer_block[am] if outer_block
80       inner_block[am] if inner_block
81     else
82       msg = "[#{am.base}] Adding #{'singleton ' if am.singleton?}method #{klass}##{method}"
83 
84       msg << if irb?(callstack)
85         " in (irb:#{IRB.conf[:MAIN_CONTEXT].instance_variable_get(:@line_no)})"
86       else
87         " at #{where(callstack)}"
88       end
89 
90       puts msg
91     end
92   }]
93 end
find(conditions = {}) click to toggle source
    # File lib/added_methods.rb
118 def find(conditions = {})
119   conditions = conditions.dup
120 
121   class_condition = conditions.delete(:class)
122   file_condition  = conditions.delete(:file)
123 
124   results = []
125 
126   all_methods.each { |klass, files|
127     if class_condition
128       next unless class_condition.is_a?(Array) ? class_condition.include?(klass) : klass == class_condition
129     end
130 
131     files.each { |file, entries|
132       if file_condition
133         next unless file_condition.is_a?(Regexp) ? file =~ file_condition : file == file_condition
134       end
135 
136       entries.each { |am|
137         results << am if conditions.all? { |key, value|
138           case value
139             when Array, Range then value.include?(am[key])
140             when Regexp       then value =~ am[key].to_s
141             else                   value == am[key]
142           end
143         }
144       }
145     }
146   }
147 
148   results
149 end
find_by_class(*classes) click to toggle source
    # File lib/added_methods.rb
151 def find_by_class(*classes)
152   conditions = classes.last.is_a?(Hash) ? classes.pop : {}
153   find(conditions.merge(:class => classes))
154 end
find_by_name(*names) click to toggle source
    # File lib/added_methods.rb
156 def find_by_name(*names)
157   conditions = names.last.is_a?(Hash) ? names.pop : {}
158   find(conditions.merge(:name => names.map { |m| m.to_s }))
159 end
find_one_by_name_or_class(name_or_class, conditions = {}) click to toggle source
    # File lib/added_methods.rb
161 def find_one_by_name_or_class(name_or_class, conditions = {})
162   (name_or_class.is_a?(Class) ?
163     find_by_class(name_or_class) :
164     find_by_name(name_or_class)
165   ).last
166 end
Also aliased as: []
init(regexp = nil, klasses = [], &block) click to toggle source
   # File lib/added_methods.rb
45 def init(regexp = nil, klasses = [], &block)
46   init_script_lines
47   patch_readline_history
48 
49   define_callback(:__init, regexp, klasses, &block) if regexp
50   install_callbacks
51 end
install_callbacks(bases = [Object, Class, Module, Kernel]) click to toggle source
    # File lib/added_methods.rb
104 def install_callbacks(bases = [Object, Class, Module, Kernel])
105   bases.each { |base|
106     [base, singleton_class(base)].each { |b|
107       b.send(:define_method, :method_added)           { |id| AddedMethods.callback(b, self, id, false) }
108       b.send(:define_method, :singleton_method_added) { |id| AddedMethods.callback(b, self, id, true)  }
109     }
110   }
111 end
remove_callback(name) click to toggle source
   # File lib/added_methods.rb
95 def remove_callback(name)
96   callbacks.delete_if { |n, _| n == name }
97 end
replace_callback(name, regexp = nil, klasses = [], &outer_block) click to toggle source
    # File lib/added_methods.rb
 99 def replace_callback(name, regexp = nil, klasses = [], &outer_block)
100   remove_callback(name)
101   define_callback(name, regexp, klasses, &outer_block)
102 end

Private Instance Methods

add_method(am) click to toggle source
    # File lib/added_methods.rb
239 def add_method(am)
240   am = AddedMethod.new(am) unless am.is_a?(AddedMethod)
241   all_methods[am.klass][am.file] << am
242 end
added_method_callback() click to toggle source
    # File lib/added_methods.rb
235 def added_method_callback
236   lambda { |am| add_method(am) }
237 end
defined_in_irb?(callstack) click to toggle source
    # File lib/added_methods.rb
217 def defined_in_irb?(callstack)
218   callstack = callstack.dup
219 
220   callstack.shift  # ignore immediate caller
221   callstack.reject! { |c| c =~ /\(irb\):|:in `irb_binding'/ }
222   callstack.pop if callstack.last =~ %r{/irb/workspace\.rb:}
223 
224   callstack.empty?
225 end
have_readline_history?() click to toggle source
    # File lib/added_methods.rb
213 def have_readline_history?
214   Object.const_defined?(:Readline) && Readline.const_defined?(:HISTORY)
215 end
identify_added_method(base, klass, id, singleton, callstack) click to toggle source
    # File lib/added_methods.rb
244   def identify_added_method(base, klass, id, singleton, callstack)
245     am = {
246       :base      => base,
247       :class     => klass,
248       :name      => id.id2name,
249       :singleton => singleton
250     }
251 
252     if irb?(callstack)
253       am.update(
254         :file => HISTFILENAME,
255         :line => Readline::HISTORY.size,
256         :def  => begin Readline::HISTORY[-1] rescue IndexError end
257       )
258     else
259       file, line, _ = where(callstack).split(':')
260       line = line.to_i
261 
262       am.update(
263         :file => file,
264         :line => line,
265         :def  => (SCRIPT_LINES__[file] || [])[line - 1]
266       )
267     end
268 
269     AddedMethod.new(am)
270   end
271 
272 end
init_all_methods() click to toggle source
    # File lib/added_methods.rb
189 def init_all_methods
190   unless const_defined?(:ALL_METHODS)
191     const_set(:ALL_METHODS, Hash.new { |h, k|
192       h[k] = Hash.new { |i, j| i[j] = [] }
193     })
194   end
195 end
init_callbacks() click to toggle source
    # File lib/added_methods.rb
182 def init_callbacks
183   unless const_defined?(:CALLBACKS)
184     const_set(:CALLBACKS, [])
185     define_callback(:__default, //, [], &added_method_callback)
186   end
187 end
init_script_lines() click to toggle source
    # File lib/added_methods.rb
176 def init_script_lines
177   unless Object.const_defined?(:SCRIPT_LINES__)
178     Object.const_set(:SCRIPT_LINES__, {})
179   end
180 end
irb?(callstack) click to toggle source
    # File lib/added_methods.rb
227 def irb?(callstack)
228   have_readline_history? && defined_in_irb?(callstack)
229 end
patch_readline_history() click to toggle source
    # File lib/added_methods.rb
197 def patch_readline_history
198   return unless have_readline_history?
199   return if Readline::HISTORY.respond_to?(:_added_methods_original_push)
200 
201   class << Readline::HISTORY
202     alias_method :_added_methods_original_push, :push
203 
204     def push(l)
205       (SCRIPT_LINES__[HISTFILENAME] ||= Readline::HISTORY.to_a) << l
206       _added_methods_original_push(l)
207     end
208 
209     alias_method :<<, :push
210   end
211 end
singleton_class(klass = self) click to toggle source
    # File lib/added_methods.rb
172 def singleton_class(klass = self)
173   class << klass; self; end
174 end
where(callstack, default = '(none):0') click to toggle source
    # File lib/added_methods.rb
231 def where(callstack, default = '(none):0')
232   callstack.find { |i| i !~ /:in `.*'/ } || callstack[1] || default
233 end