ruby-nuggets 0.5.2 → 0.5.4

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.5.2
5
+ This documentation refers to ruby-nuggets version 0.5.4
6
6
 
7
7
 
8
8
  == DESCRIPTION
@@ -1,407 +1,6 @@
1
- #--
2
- ###############################################################################
3
- # #
4
- # A component of ruby-nuggets, some extensions to the Ruby programming #
5
- # language. #
6
- # #
7
- # Copyright (C) 2007-2008 Jens Wille #
8
- # #
9
- # Authors: #
10
- # Jens Wille <jens.wille@uni-koeln.de> #
11
- # #
12
- # ruby-nuggets is free software; you can redistribute it and/or modify it #
13
- # under the terms of the GNU General Public License as published by the Free #
14
- # Software Foundation; either version 3 of the License, or (at your option) #
15
- # any later version. #
16
- # #
17
- # ruby-nuggets is distributed in the hope that it will be useful, but WITHOUT #
18
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
19
- # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
20
- # more details. #
21
- # #
22
- # You should have received a copy of the GNU General Public License along #
23
- # with ruby-nuggets. If not, see <http://www.gnu.org/licenses/>. #
24
- # #
25
- ###############################################################################
26
- #++
27
-
28
- begin
29
- require 'ruby2ruby'
30
- rescue LoadError
31
- end
1
+ # backwards compatibility
2
+ require 'added_methods'
32
3
 
33
4
  module Util
34
-
35
- # Watch for added methods and record them. Inspired by unroller,
36
- # <http://unroller.rubyforge.org/classes/Unroller.html#M000034>.
37
- #
38
- # Example:
39
- #
40
- # require 'rubygems'
41
- # require 'nuggets/util/added_methods/init'
42
- #
43
- # require 'some/library/or/whatever'
44
- #
45
- # matches = Util::AddedMethods.find(
46
- # :name => 'method_name',
47
- # :class => SomeClass # optional
48
- # )
49
- #
50
- # # get the class(es) where matching method(s) were defined
51
- # matches.each { |am| puts am.klass # also am[:klass] or am[:class] }
52
- #
53
- # # assume the first one is the one we're looking for
54
- # am = matches.first
55
- #
56
- # # is it a singleton method?
57
- # puts am.singleton?
58
- #
59
- # # where exactly has it been defined?
60
- # puts "#{am.file}, line #{am.line}"
61
- #
62
- # # now get its source
63
- # puts am # implies #to_s, you can also call #extract_source directly
64
- #
65
- # TODO:
66
- # - multi-line statements in irb w/o ruby2ruby? (=> extract_source)
67
- # - polishing!
68
-
69
- module AddedMethods
70
-
71
- extend self
72
-
73
- HISTFILENAME = '(Readline::HISTORY)'.freeze unless const_defined?(:HISTFILENAME)
74
-
75
- class AddedMethod
76
-
77
- attr_accessor :base, :klass, :name, :singleton, :file, :line, :def
78
-
79
- def initialize(args = {})
80
- args.each { |key, value|
81
- send("#{key}=", value)
82
- }
83
- end
84
-
85
- alias_method 'class=', 'klass='
86
- alias_method :singleton?, :singleton
87
-
88
- def [](key)
89
- send(key.to_sym == :class ? :klass : key)
90
- end
91
-
92
- def source
93
- @source ||= extract_source
94
- end
95
-
96
- def extract_source(num_lines = nil)
97
- lines = extract_source_from_script_lines(num_lines)
98
-
99
- # try to make sure we correctly extracted the method
100
- # definition, otherwise try to get it from Ruby2Ruby
101
- lines.first =~ /\b#{name}\b/ ? lines : extract_source_from_r2r || lines
102
- end
103
-
104
- def to_s
105
- str = "# File #{file}, line #{line}"
106
-
107
- case lines = source
108
- when Array
109
- num = line - 1
110
- width = (num + lines.size).to_s.length
111
-
112
- lines.map! { |l| "%0#{width}d: %s" % [num += 1, l] }
113
-
114
- "#{' ' * width} #{str}\n#{lines}"
115
- when String
116
- "#{str}#{lines}"
117
- else
118
- str
119
- end
120
- end
121
-
122
- private
123
-
124
- def extract_source_from_script_lines(num_lines = nil)
125
- return unless Object.const_defined?(:SCRIPT_LINES__)
126
- return unless script_lines = SCRIPT_LINES__[file]
127
-
128
- start, from, to = line - 1, line, script_lines.size - 1
129
-
130
- # suppose we're already in a block
131
- in_block = 1
132
-
133
- num_lines ||= case definition = script_lines[start]
134
- # def ... end, or do ... end style block
135
- when /\b(?:def|do)\b/
136
- definition =~ /\bend\b/ ? 1 : begin
137
- from.upto(to) { |i|
138
- case line = script_lines[i]
139
- when /[^;\s]\s+(?:if|unless)\b/
140
- # probably postfix conditional, ignore
141
- when /\b(?:if|unless|while|until|def|do)\b/
142
- in_block += 1
143
- when /\bend\b/
144
- in_block -= 1
145
- end
146
-
147
- break i - start + 1 if in_block.zero?
148
- }
149
- end
150
- # { ... } style block
151
- when /\bdefine_method\b/
152
- from.upto(to) { |i|
153
- line = script_lines[i]
154
-
155
- in_block += line.count('{')
156
- in_block -= line.count('}')
157
-
158
- break i - start + 1 if in_block.zero?
159
- }
160
- else
161
- 1
162
- end
163
-
164
- script_lines[start, num_lines]
165
- end
166
-
167
- # Use Ruby2Ruby as a last resort. But note that it only
168
- # ever finds the *latest*, i.e. currently active, method
169
- # definition, not necessarily the one we're looking for.
170
- def extract_source_from_r2r
171
- if Object.const_defined?(:Ruby2Ruby)
172
- " [R2R]\n#{Ruby2Ruby.translate(klass, name)}"
173
- end
174
- end
175
-
176
- end
177
-
178
- def init(regexp = nil, klasses = [], &block)
179
- init_script_lines
180
- patch_readline_history
181
-
182
- define_callback(:__init, regexp, klasses, &block) if regexp
183
- install_callbacks
184
- end
185
-
186
- def callbacks
187
- init_callbacks
188
- CALLBACKS
189
- end
190
-
191
- def callback(*args, &inner_block)
192
- callback_args = [identify_added_method(*args << caller), caller, inner_block]
193
- callbacks.each { |name, callback| callback[*callback_args] }
194
- end
195
-
196
- def define_callback(name, regexp = //, klasses = [], &outer_block)
197
- raise TypeError, "wrong argument type #{name.class} (expected Symbol)" unless name.is_a?(Symbol)
198
- raise "callback with name #{name} already exists" if callbacks.assoc(name)
199
-
200
- raise TypeError, "wrong argument type #{regexp.class} (expected Regexp)" unless regexp.is_a?(Regexp)
201
- raise TypeError, "wrong argument type #{klasses.class} (expected container object)" unless klasses.respond_to?(:empty?) && klasses.respond_to?(:include?)
202
-
203
- callbacks << [name, lambda { |am, callstack, inner_block|
204
- method, klass = am.name, am.klass
205
-
206
- return if %w[method_added singleton_method_added].include?(method)
207
-
208
- return unless klasses.empty? || klasses.include?(klass.to_s)
209
- return unless method =~ regexp
210
-
211
- if outer_block || inner_block
212
- outer_block[am] if outer_block
213
- inner_block[am] if inner_block
214
- else
215
- msg = "[#{am.base}] Adding #{'singleton ' if am.singleton?}method #{klass}##{method}"
216
-
217
- msg << if irb?(callstack)
218
- " in (irb:#{IRB.conf[:MAIN_CONTEXT].instance_variable_get(:@line_no)})"
219
- else
220
- " at #{where(callstack)}"
221
- end
222
-
223
- puts msg
224
- end
225
- }]
226
- end
227
-
228
- def remove_callback(name)
229
- callbacks.delete_if { |n, _| n == name }
230
- end
231
-
232
- def replace_callback(name, regexp = nil, klasses = [], &outer_block)
233
- remove_callback(name)
234
- define_callback(name, regexp, klasses, &outer_block)
235
- end
236
-
237
- def install_callbacks(bases = [Object, Class, Module, Kernel])
238
- bases.each { |base|
239
- [base, singleton_class(base)].each { |b|
240
- b.send(:define_method, :method_added) { |id| AddedMethods.callback(b, self, id, false) }
241
- b.send(:define_method, :singleton_method_added) { |id| AddedMethods.callback(b, self, id, true) }
242
- }
243
- }
244
- end
245
-
246
- def all_methods
247
- init_all_methods
248
- ALL_METHODS
249
- end
250
-
251
- def find(conditions = {})
252
- conditions = conditions.dup
253
-
254
- class_condition = conditions.delete(:class)
255
- file_condition = conditions.delete(:file)
256
-
257
- results = []
258
-
259
- all_methods.each { |klass, files|
260
- if class_condition
261
- next unless class_condition.is_a?(Array) ? class_condition.include?(klass) : klass == class_condition
262
- end
263
-
264
- files.each { |file, entries|
265
- if file_condition
266
- next unless file_condition.is_a?(Regexp) ? file =~ file_condition : file == file_condition
267
- end
268
-
269
- entries.each { |am|
270
- results << am if conditions.all? { |key, value|
271
- case value
272
- when Array, Range then value.include?(am[key])
273
- when Regexp then value =~ am[key].to_s
274
- else value == am[key]
275
- end
276
- }
277
- }
278
- }
279
- }
280
-
281
- results
282
- end
283
-
284
- def find_by_class(*classes)
285
- conditions = classes.last.is_a?(Hash) ? classes.pop : {}
286
- find(conditions.merge(:class => classes))
287
- end
288
-
289
- def find_by_name(*names)
290
- conditions = names.last.is_a?(Hash) ? names.pop : {}
291
- find(conditions.merge(:name => names.map { |m| m.to_s }))
292
- end
293
-
294
- def find_one_by_name_or_class(name_or_class, conditions = {})
295
- (name_or_class.is_a?(Class) ?
296
- find_by_class(name_or_class) :
297
- find_by_name(name_or_class)
298
- ).last
299
- end
300
-
301
- alias_method :[], :find_one_by_name_or_class
302
-
303
- private
304
-
305
- def singleton_class(klass = self)
306
- class << klass; self; end
307
- end
308
-
309
- def init_script_lines
310
- unless Object.const_defined?(:SCRIPT_LINES__)
311
- Object.const_set(:SCRIPT_LINES__, {})
312
- end
313
- end
314
-
315
- def init_callbacks
316
- unless const_defined?(:CALLBACKS)
317
- const_set(:CALLBACKS, [])
318
- define_callback(:__default, //, [], &added_method_callback)
319
- end
320
- end
321
-
322
- def init_all_methods
323
- unless const_defined?(:ALL_METHODS)
324
- const_set(:ALL_METHODS, Hash.new { |h, k|
325
- h[k] = Hash.new { |i, j| i[j] = [] }
326
- })
327
- end
328
- end
329
-
330
- def patch_readline_history
331
- return unless have_readline_history?
332
- return if Readline::HISTORY.respond_to?(:_added_methods_original_push)
333
-
334
- class << Readline::HISTORY
335
- alias_method :_added_methods_original_push, :push
336
-
337
- def push(l)
338
- (SCRIPT_LINES__[HISTFILENAME] ||= Readline::HISTORY.to_a) << l
339
- _added_methods_original_push(l)
340
- end
341
-
342
- alias_method :<<, :push
343
- end
344
- end
345
-
346
- def have_readline_history?
347
- Object.const_defined?(:Readline) && Readline.const_defined?(:HISTORY)
348
- end
349
-
350
- def defined_in_irb?(callstack)
351
- callstack = callstack.dup
352
-
353
- callstack.shift # ignore immediate caller
354
- callstack.reject! { |c| c =~ /\(irb\):|:in `irb_binding'/ }
355
- callstack.pop if callstack.last =~ %r{/irb/workspace\.rb:}
356
-
357
- callstack.empty?
358
- end
359
-
360
- def irb?(callstack)
361
- have_readline_history? && defined_in_irb?(callstack)
362
- end
363
-
364
- def where(callstack, default = '(none):0')
365
- callstack.find { |i| i !~ /:in `.*'/ } || callstack[1] || default
366
- end
367
-
368
- def added_method_callback
369
- lambda { |am| add_method(am) }
370
- end
371
-
372
- def add_method(am)
373
- am = AddedMethod.new(am) unless am.is_a?(AddedMethod)
374
- all_methods[am.klass][am.file] << am
375
- end
376
-
377
- def identify_added_method(base, klass, id, singleton, callstack)
378
- am = {
379
- :base => base,
380
- :class => klass,
381
- :name => id.id2name,
382
- :singleton => singleton
383
- }
384
-
385
- if irb?(callstack)
386
- am.update(
387
- :file => HISTFILENAME,
388
- :line => Readline::HISTORY.size,
389
- :def => begin Readline::HISTORY[-1] rescue IndexError end
390
- )
391
- else
392
- file, line, _ = where(callstack).split(':')
393
- line = line.to_i
394
-
395
- am.update(
396
- :file => file,
397
- :line => line,
398
- :def => (SCRIPT_LINES__[file] || [])[line - 1]
399
- )
400
- end
401
-
402
- AddedMethod.new(am)
403
- end
404
-
405
- end
406
-
5
+ AddedMethods = ::AddedMethods
407
6
  end
@@ -4,7 +4,7 @@ module Nuggets
4
4
 
5
5
  MAJOR = 0
6
6
  MINOR = 5
7
- TINY = 2
7
+ TINY = 4
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.5.2
4
+ version: 0.5.4
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: 2009-03-12 00:00:00 +01:00
12
+ date: 2009-03-27 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -106,15 +106,15 @@ has_rdoc: true
106
106
  homepage: http://prometheus.rubyforge.org/ruby-nuggets
107
107
  post_install_message:
108
108
  rdoc_options:
109
- - --main
110
- - README
111
- - --line-numbers
112
109
  - --inline-source
113
110
  - --title
114
111
  - ruby-nuggets Application documentation
115
- - --all
116
112
  - --charset
117
113
  - UTF-8
114
+ - --main
115
+ - README
116
+ - --all
117
+ - --line-numbers
118
118
  require_paths:
119
119
  - lib
120
120
  required_ruby_version: !ruby/object:Gem::Requirement