ruby-nuggets 0.2.5.256 → 0.2.6.257

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  == VERSION
4
4
 
5
- This documentation refers to ruby-nuggets version 0.2.5
5
+ This documentation refers to ruby-nuggets version 0.2.6
6
6
 
7
7
 
8
8
  == DESCRIPTION
@@ -1,323 +1,330 @@
1
- # watch for added methods and record them
2
- # cf. <http://unroller.rubyforge.org/classes/Unroller.html#M000034>
3
-
4
- # TODO:
5
- # - multi-line statements in irb (extract_source)
6
- # - polishing!
7
-
8
- require 'ruby2ruby'
9
-
10
- module AddedMethods
1
+ begin
2
+ require 'ruby2ruby'
3
+ rescue LoadError
4
+ end
11
5
 
12
- extend self
6
+ module Util
13
7
 
14
- HISTFILENAME = '(Readline::HISTORY)'.freeze
8
+ # Watch for added methods and record them. Inspired by unroller,
9
+ # <http://unroller.rubyforge.org/classes/Unroller.html#M000034>.
10
+ #
11
+ # TODO:
12
+ # - multi-line statements in irb w/o ruby2ruby? (=> extract_source)
13
+ # - polishing!
15
14
 
16
- class AddedMethod < Hash
15
+ module AddedMethods
17
16
 
18
- def initialize(*args)
19
- update(*args) unless args.empty?
20
- end
17
+ extend self
21
18
 
22
- def extract_source(num_lines = nil)
23
- return unless Object.const_defined?(:SCRIPT_LINES__)
24
- return unless script_lines = SCRIPT_LINES__[file]
19
+ HISTFILENAME = '(Readline::HISTORY)'.freeze
25
20
 
26
- start, from, to = line - 1, line, script_lines.size - 1
21
+ class AddedMethod < Hash
27
22
 
28
- # suppose we're already in a block
29
- in_block = 1
23
+ def initialize(*args)
24
+ update(*args) unless args.empty?
25
+ end
30
26
 
31
- num_lines ||= case definition = script_lines[start]
32
- # def ... end, or do ... end style block
33
- when /\b(?:def|do)\b/
34
- definition =~ /\bend\b/ ? 1 : begin
27
+ def extract_source(num_lines = nil)
28
+ return unless Object.const_defined?(:SCRIPT_LINES__)
29
+ return unless script_lines = SCRIPT_LINES__[file]
30
+
31
+ start, from, to = line - 1, line, script_lines.size - 1
32
+
33
+ # suppose we're already in a block
34
+ in_block = 1
35
+
36
+ num_lines ||= case definition = script_lines[start]
37
+ # def ... end, or do ... end style block
38
+ when /\b(?:def|do)\b/
39
+ definition =~ /\bend\b/ ? 1 : begin
40
+ from.upto(to) { |i|
41
+ case line = script_lines[i]
42
+ when /[^;\s]\s+(?:if|unless)\b/
43
+ # probably postfix conditional, ignore
44
+ when /\b(?:if|unless|while|until|def|do)\b/
45
+ in_block += 1
46
+ when /\bend\b/
47
+ in_block -= 1
48
+ end
49
+
50
+ break i - start + 1 if in_block.zero?
51
+ }
52
+ end
53
+ # { ... } style block
54
+ when /\bdefine_method\b/
35
55
  from.upto(to) { |i|
36
- case line = script_lines[i]
37
- when /[^;\s]\s+(?:if|unless)\b/
38
- # probably postfix conditional, ignore
39
- when /\b(?:if|unless|while|until|def|do)\b/
40
- in_block += 1
41
- when /\bend\b/
42
- in_block -= 1
43
- end
56
+ line = script_lines[i]
57
+
58
+ in_block += line.count('{')
59
+ in_block -= line.count('}')
44
60
 
45
61
  break i - start + 1 if in_block.zero?
46
62
  }
47
- end
48
- # { ... } style block
49
- when /\bdefine_method\b/
50
- from.upto(to) { |i|
51
- line = script_lines[i]
63
+ else
64
+ 1
65
+ end
52
66
 
53
- in_block += line.count('{')
54
- in_block -= line.count('}')
67
+ lines = script_lines[start, num_lines]
55
68
 
56
- break i - start + 1 if in_block.zero?
57
- }
69
+ # try to make sure we correctly extracted the method definition
70
+ if lines.first =~ /\b#{name}\b/ || !Object.const_defined?(:Ruby2Ruby)
71
+ lines
58
72
  else
59
- 1
73
+ # use Ruby2Ruby as a last resort. but note that it only
74
+ # ever finds the *latest*, i.e. currently active, method
75
+ # definition, not necessarily the one we're looking for.
76
+ "#### [R2R] ####\n#{Ruby2Ruby.translate(klass, name)}"
77
+ end
60
78
  end
61
79
 
62
- lines = script_lines[start, num_lines]
63
-
64
- # try to make sure we correctly extracted the method definition
65
- if lines.first =~ /\b#{name}\b/
66
- lines
67
- else
68
- # use Ruby2Ruby as a last resort. but note that it only
69
- # ever finds the *latest*, i.e. currently active, method
70
- # definition, not necessarily the one we're looking for.
71
- "#### [R2R] ####\n#{Ruby2Ruby.translate(klass, name)}"
80
+ def to_s(num_lines = nil)
81
+ "# File #{file}, line #{line}\n#{extract_source(num_lines).map { |l| " #{l}" }}"
72
82
  end
73
- end
74
83
 
75
- def to_s(num_lines = nil)
76
- "# File #{file}, line #{line}\n#{extract_source(num_lines).map { |l| " #{l}" }}"
77
- end
84
+ def klass
85
+ self[:class]
86
+ end
78
87
 
79
- def klass
80
- self[:class]
81
- end
88
+ def method_missing(method, *args)
89
+ has_key?(method) ? self[method] : super
90
+ end
82
91
 
83
- def method_missing(method, *args)
84
- has_key?(method) ? self[method] : super
85
92
  end
86
93
 
87
- end
94
+ def init(regexp = nil, klasses = [], &block)
95
+ init_script_lines
96
+ patch_readline_history
88
97
 
89
- def init(regexp = nil, klasses = [], &block)
90
- init_script_lines
91
- patch_readline_history
98
+ define_callback(:__init, regexp, klasses, &block) if regexp
99
+ install_callbacks
100
+ end
92
101
 
93
- define_callback(:__init, regexp, klasses, &block) if regexp
94
- install_callbacks
95
- end
102
+ def callbacks
103
+ init_callbacks
104
+ CALLBACKS
105
+ end
96
106
 
97
- def callbacks
98
- init_callbacks
99
- CALLBACKS
100
- end
107
+ def callback(*args, &inner_block)
108
+ callback_args = [identify_added_method(*args << caller), caller, inner_block]
109
+ callbacks.each { |name, callback| callback[*callback_args] }
110
+ end
101
111
 
102
- def callback(*args, &inner_block)
103
- callback_args = [identify_added_method(*args << caller), caller, inner_block]
104
- callbacks.each { |name, callback| callback[*callback_args] }
105
- end
112
+ def define_callback(name, regexp = //, klasses = [], &outer_block)
113
+ raise TypeError, "wrong argument type #{name.class} (expected Symbol)" unless name.is_a?(Symbol)
114
+ raise "callback with name #{name} already exists" if callbacks.any? { |n, _| n == name }
106
115
 
107
- def define_callback(name, regexp = //, klasses = [], &outer_block)
108
- raise TypeError, "wrong argument type #{name.class} (expected Symbol)" unless name.is_a?(Symbol)
109
- raise "callback with name #{name} already exists" if callbacks.any? { |n, _| n == name }
116
+ raise TypeError, "wrong argument type #{regexp.class} (expected Regexp)" unless regexp.is_a?(Regexp)
117
+ raise TypeError, "wrong argument type #{klasses.class} (expected container object)" unless klasses.respond_to?(:empty?) && klasses.respond_to?(:include?)
110
118
 
111
- raise TypeError, "wrong argument type #{regexp.class} (expected Regexp)" unless regexp.is_a?(Regexp)
112
- raise TypeError, "wrong argument type #{klasses.class} (expected container object)" unless klasses.respond_to?(:empty?) && klasses.respond_to?(:include?)
119
+ callbacks << [name, lambda { |am, callstack, inner_block|
120
+ method, klass = am.values_at(:name, :class)
113
121
 
114
- callbacks << [name, lambda { |am, callstack, inner_block|
115
- method, klass = am.values_at(:name, :class)
122
+ return if %w[method_added singleton_method_added].include?(method)
116
123
 
117
- return if %w[method_added singleton_method_added].include?(method)
124
+ return unless klasses.empty? || klasses.include?(klass.to_s)
125
+ return unless method =~ regexp
118
126
 
119
- return unless klasses.empty? || klasses.include?(klass.to_s)
120
- return unless method =~ regexp
127
+ if outer_block || inner_block
128
+ outer_block[am] if outer_block
129
+ inner_block[am] if inner_block
130
+ else
131
+ msg = "[#{am.base}] Adding #{'singleton ' if am.singleton}method #{klass}##{method}"
121
132
 
122
- if outer_block || inner_block
123
- outer_block[am] if outer_block
124
- inner_block[am] if inner_block
125
- else
126
- msg = "[#{am.base}] Adding #{'singleton ' if am.singleton}method #{klass}##{method}"
133
+ msg << if irb?(callstack)
134
+ " in (irb:#{IRB.conf[:MAIN_CONTEXT].instance_variable_get(:@line_no)})"
135
+ else
136
+ " at #{where(callstack)}"
137
+ end
127
138
 
128
- msg << if irb?(callstack)
129
- " in (irb:#{IRB.conf[:MAIN_CONTEXT].instance_variable_get(:@line_no)})"
130
- else
131
- " at #{where(callstack)}"
139
+ puts msg
132
140
  end
141
+ }]
142
+ end
133
143
 
134
- puts msg
135
- end
136
- }]
137
- end
138
-
139
- def remove_callback(name)
140
- callbacks.delete_if { |n, _| n == name }
141
- end
144
+ def remove_callback(name)
145
+ callbacks.delete_if { |n, _| n == name }
146
+ end
142
147
 
143
- def replace_callback(name, regexp = nil, klasses = [], &outer_block)
144
- remove_callback(name)
145
- define_callback(name, regexp, klasses, &outer_block)
146
- end
148
+ def replace_callback(name, regexp = nil, klasses = [], &outer_block)
149
+ remove_callback(name)
150
+ define_callback(name, regexp, klasses, &outer_block)
151
+ end
147
152
 
148
- def install_callbacks(bases = [Object, Class, Module, Kernel])
149
- bases.each { |base|
150
- [base, singleton_class(base)].each { |b|
151
- b.send(:define_method, :method_added) { |id| AddedMethods.callback(b, self, id, false) }
152
- b.send(:define_method, :singleton_method_added) { |id| AddedMethods.callback(b, self, id, true) }
153
+ def install_callbacks(bases = [Object, Class, Module, Kernel])
154
+ bases.each { |base|
155
+ [base, singleton_class(base)].each { |b|
156
+ b.send(:define_method, :method_added) { |id| AddedMethods.callback(b, self, id, false) }
157
+ b.send(:define_method, :singleton_method_added) { |id| AddedMethods.callback(b, self, id, true) }
158
+ }
153
159
  }
154
- }
155
- end
160
+ end
156
161
 
157
- def all_methods
158
- init_all_methods
159
- ALL_METHODS
160
- end
162
+ def all_methods
163
+ init_all_methods
164
+ ALL_METHODS
165
+ end
161
166
 
162
- def find(conditions = {})
163
- conditions = conditions.dup
167
+ def find(conditions = {})
168
+ conditions = conditions.dup
164
169
 
165
- class_condition = conditions.delete(:class)
166
- file_condition = conditions.delete(:file)
170
+ class_condition = conditions.delete(:class)
171
+ file_condition = conditions.delete(:file)
167
172
 
168
- results = []
173
+ results = []
169
174
 
170
- all_methods.each { |klass, files|
171
- if class_condition
172
- next unless class_condition.is_a?(Array) ? class_condition.include?(klass) : klass == class_condition
173
- end
174
-
175
- files.each { |file, entries|
176
- if file_condition
177
- next unless file_condition.is_a?(Regexp) ? file =~ file_condition : file == file_condition
175
+ all_methods.each { |klass, files|
176
+ if class_condition
177
+ next unless class_condition.is_a?(Array) ? class_condition.include?(klass) : klass == class_condition
178
178
  end
179
179
 
180
- entries.each { |entry|
181
- results << entry.merge(
182
- :class => klass,
183
- :file => file
184
- ) if conditions.all? { |key, value|
185
- case value
186
- when Array: value.include?(entry[key])
187
- when Regexp: entry[key].to_s =~ value
188
- else entry[key] == value
189
- end
180
+ files.each { |file, entries|
181
+ if file_condition
182
+ next unless file_condition.is_a?(Regexp) ? file =~ file_condition : file == file_condition
183
+ end
184
+
185
+ entries.each { |entry|
186
+ results << entry.merge(
187
+ :class => klass,
188
+ :file => file
189
+ ) if conditions.all? { |key, value|
190
+ case value
191
+ when Array: value.include?(entry[key])
192
+ when Regexp: entry[key].to_s =~ value
193
+ else entry[key] == value
194
+ end
195
+ }
190
196
  }
191
197
  }
192
198
  }
193
- }
194
199
 
195
- results
196
- end
200
+ results
201
+ end
197
202
 
198
- def find_by_class(*classes)
199
- conditions = classes.last.is_a?(Hash) ? classes.pop : {}
200
- find(conditions.merge(:class => classes))
201
- end
203
+ def find_by_class(*classes)
204
+ conditions = classes.last.is_a?(Hash) ? classes.pop : {}
205
+ find(conditions.merge(:class => classes))
206
+ end
202
207
 
203
- def find_by_name(*names)
204
- conditions = names.last.is_a?(Hash) ? names.pop : {}
205
- names.inject([]) { |memo, name|
206
- memo += find(conditions.merge(:name => name.to_s))
207
- }
208
- end
208
+ def find_by_name(*names)
209
+ conditions = names.last.is_a?(Hash) ? names.pop : {}
210
+ names.inject([]) { |memo, name|
211
+ memo += find(conditions.merge(:name => name.to_s))
212
+ }
213
+ end
209
214
 
210
- def find_one_by_name_or_class(name_or_class, conditions = {})
211
- (name_or_class.is_a?(Class) ?
212
- find_by_class(name_or_class) :
213
- find_by_name(name_or_class)
214
- ).last
215
- end
215
+ def find_one_by_name_or_class(name_or_class, conditions = {})
216
+ (name_or_class.is_a?(Class) ?
217
+ find_by_class(name_or_class) :
218
+ find_by_name(name_or_class)
219
+ ).last
220
+ end
216
221
 
217
- alias_method :[], :find_one_by_name_or_class
222
+ alias_method :[], :find_one_by_name_or_class
218
223
 
219
- private
224
+ private
220
225
 
221
- def singleton_class(klass = self)
222
- class << klass; self; end
223
- end
226
+ def singleton_class(klass = self)
227
+ class << klass; self; end
228
+ end
224
229
 
225
- def init_script_lines
226
- unless Object.const_defined?(:SCRIPT_LINES__)
227
- Object.const_set(:SCRIPT_LINES__, {})
230
+ def init_script_lines
231
+ unless Object.const_defined?(:SCRIPT_LINES__)
232
+ Object.const_set(:SCRIPT_LINES__, {})
233
+ end
228
234
  end
229
- end
230
235
 
231
- def init_callbacks
232
- unless const_defined?(:CALLBACKS)
233
- const_set(:CALLBACKS, [])
234
- define_callback(:__default, //, [], &added_method_callback)
236
+ def init_callbacks
237
+ unless const_defined?(:CALLBACKS)
238
+ const_set(:CALLBACKS, [])
239
+ define_callback(:__default, //, [], &added_method_callback)
240
+ end
235
241
  end
236
- end
237
242
 
238
- def init_all_methods
239
- unless const_defined?(:ALL_METHODS)
240
- const_set(:ALL_METHODS, Hash.new { |h, k|
241
- h[k] = Hash.new { |i, j|
242
- i[j] = []
243
- }
244
- })
243
+ def init_all_methods
244
+ unless const_defined?(:ALL_METHODS)
245
+ const_set(:ALL_METHODS, Hash.new { |h, k|
246
+ h[k] = Hash.new { |i, j|
247
+ i[j] = []
248
+ }
249
+ })
250
+ end
245
251
  end
246
- end
247
252
 
248
- def patch_readline_history
249
- return unless have_readline_history?
250
- return if Readline::HISTORY.respond_to?(:_added_methods_original_push)
253
+ def patch_readline_history
254
+ return unless have_readline_history?
255
+ return if Readline::HISTORY.respond_to?(:_added_methods_original_push)
251
256
 
252
- class << Readline::HISTORY
253
- alias_method :_added_methods_original_push, :push
257
+ class << Readline::HISTORY
258
+ alias_method :_added_methods_original_push, :push
254
259
 
255
- def push(l)
256
- (SCRIPT_LINES__[HISTFILENAME] ||= Readline::HISTORY.to_a) << l
257
- _added_methods_original_push(l)
260
+ def push(l)
261
+ (SCRIPT_LINES__[HISTFILENAME] ||= Readline::HISTORY.to_a) << l
262
+ _added_methods_original_push(l)
263
+ end
264
+
265
+ alias_method :<<, :push
258
266
  end
267
+ end
259
268
 
260
- alias_method :<<, :push
269
+ def have_readline_history?
270
+ Object.const_defined?(:Readline) && Readline.const_defined?(:HISTORY)
261
271
  end
262
- end
263
272
 
264
- def have_readline_history?
265
- Object.const_defined?(:Readline) && Readline.const_defined?(:HISTORY)
266
- end
273
+ def defined_in_irb?(callstack)
274
+ callstack = callstack.dup
267
275
 
268
- def defined_in_irb?(callstack)
269
- callstack = callstack.dup
276
+ callstack.shift # ignore immediate caller
277
+ callstack.reject! { |c| c =~ /\(irb\):|:in `irb_binding'/ }
278
+ callstack.pop if callstack.last =~ %r{/irb/workspace\.rb:}
270
279
 
271
- callstack.shift # ignore immediate caller
272
- callstack.reject! { |c| c =~ /\(irb\):|:in `irb_binding'/ }
273
- callstack.pop if callstack.last =~ %r{/irb/workspace\.rb:}
280
+ callstack.empty?
281
+ end
274
282
 
275
- callstack.empty?
276
- end
283
+ def irb?(callstack)
284
+ have_readline_history? && defined_in_irb?(callstack)
285
+ end
277
286
 
278
- def irb?(callstack)
279
- have_readline_history? && defined_in_irb?(callstack)
280
- end
287
+ def where(callstack, default = '(none):0')
288
+ callstack.find { |i| i !~ /:in `.*'/ } || callstack[1] || default
289
+ end
281
290
 
282
- def where(callstack, default = '(none):0')
283
- callstack.find { |i| i !~ /:in `.*'/ } || callstack[1] || default
284
- end
291
+ def added_method_callback
292
+ lambda { |am| add_method(am) }
293
+ end
285
294
 
286
- def added_method_callback
287
- lambda { |am| add_method(am) }
288
- end
295
+ def add_method(am)
296
+ am = AddedMethod.new(am) unless am.is_a?(AddedMethod)
297
+ all_methods[am.klass][am.file] << am
298
+ end
289
299
 
290
- def add_method(am)
291
- am = AddedMethod.new(am) unless am.is_a?(AddedMethod)
292
- all_methods[am.klass][am.file] << am
293
- end
300
+ def identify_added_method(base, klass, id, singleton, callstack)
301
+ am = {
302
+ :base => base,
303
+ :class => klass,
304
+ :name => id.id2name,
305
+ :singleton => singleton
306
+ }
307
+
308
+ if irb?(callstack)
309
+ am.update(
310
+ :file => HISTFILENAME,
311
+ :line => Readline::HISTORY.size,
312
+ :source => begin Readline::HISTORY[-1] rescue IndexError end
313
+ )
314
+ else
315
+ file, line, _ = where(callstack).split(':')
316
+ line = line.to_i
317
+
318
+ am.update(
319
+ :file => file,
320
+ :line => line,
321
+ :source => (SCRIPT_LINES__[file] || [])[line - 1]
322
+ )
323
+ end
294
324
 
295
- def identify_added_method(base, klass, id, singleton, callstack)
296
- am = {
297
- :base => base,
298
- :class => klass,
299
- :name => id.id2name,
300
- :singleton => singleton
301
- }
302
-
303
- if irb?(callstack)
304
- am.update(
305
- :file => HISTFILENAME,
306
- :line => Readline::HISTORY.size,
307
- :source => begin Readline::HISTORY[-1] rescue IndexError end
308
- )
309
- else
310
- file, line, _ = where(callstack).split(':')
311
- line = line.to_i
312
-
313
- am.update(
314
- :file => file,
315
- :line => line,
316
- :source => (SCRIPT_LINES__[file] || [])[line - 1]
317
- )
325
+ AddedMethod.new(am)
318
326
  end
319
327
 
320
- AddedMethod.new(am)
321
328
  end
322
329
 
323
330
  end
@@ -1,3 +1,3 @@
1
1
  # just a short-cut
2
- require "#{File.dirname(__FILE__)}.rb"
3
- AddedMethods.init
2
+ require File.dirname(__FILE__)
3
+ Util::AddedMethods.init
@@ -4,7 +4,7 @@ module Nuggets
4
4
 
5
5
  MAJOR = 0
6
6
  MINOR = 2
7
- TINY = 5
7
+ TINY = 6
8
8
 
9
9
  class << self
10
10
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-nuggets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5.256
4
+ version: 0.2.6.257
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jens Wille
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-07-15 00:00:00 +02:00
12
+ date: 2008-07-23 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies: []
15
15