rmtools 1.1.11 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/Manifest.txt +16 -21
  2. data/README.txt +17 -5
  3. data/Rakefile +1 -1
  4. data/lib/rmtools/console/coloring.rb +58 -42
  5. data/lib/rmtools/console/highlight.rb +1 -1
  6. data/lib/rmtools/core/arguments.rb +7 -4
  7. data/lib/rmtools/core/js.rb +6 -5
  8. data/lib/rmtools/core/kernel.rb +37 -1
  9. data/lib/rmtools/core/module.rb +1 -1
  10. data/lib/rmtools/{debug → dev}/binding.rb +6 -6
  11. data/lib/rmtools/{experimental → dev}/blackhole.rb +0 -0
  12. data/lib/rmtools/dev/code_reader.rb +431 -0
  13. data/lib/rmtools/{debug → dev}/highlight.rb +2 -2
  14. data/lib/rmtools/{debug → dev}/logging.rb +44 -47
  15. data/lib/rmtools/{debug → dev}/observing.rb +8 -2
  16. data/lib/rmtools/dev/present.rb +63 -0
  17. data/lib/rmtools/{debug → dev}/timer.rb +3 -3
  18. data/lib/rmtools/{debug → dev}/trace_format.rb +3 -9
  19. data/lib/rmtools/{debug → dev}/traceback.rb +1 -1
  20. data/lib/rmtools/{debug.rb → dev.rb} +0 -0
  21. data/lib/rmtools/dev_min.rb +2 -0
  22. data/lib/rmtools/enumerable/array.rb +12 -1
  23. data/lib/rmtools/enumerable/array_iterators.rb +5 -3
  24. data/lib/rmtools/enumerable/common.rb +0 -2
  25. data/lib/rmtools/enumerable/hash.rb +10 -4
  26. data/lib/rmtools/enumerable/object_space.rb +11 -9
  27. data/lib/rmtools/enumerable/range.rb +21 -0
  28. data/lib/rmtools/fs/tools.rb +6 -2
  29. data/lib/rmtools/install.rb +4 -2
  30. data/lib/rmtools/lang/cyrillic.rb +2 -2
  31. data/lib/rmtools/lang/{shortcuts.rb → helpers.rb} +0 -0
  32. data/lib/rmtools/load.rb +1 -1
  33. data/lib/rmtools/text/regexp.rb +74 -0
  34. data/lib/rmtools/text/string_rtl.rb +28 -0
  35. data/lib/rmtools/text/string_scanner.rb +19 -9
  36. data/lib/rmtools/text/string_simple.rb +11 -3
  37. data/lib/rmtools/text/string_split.rb +1 -5
  38. data/lib/rmtools/xml/node.rb +1 -1
  39. data/lib/rmtools/xml/string.rb +2 -2
  40. data/lib/rmtools.rb +1 -8
  41. data/lib/rmtools_dev.rb +6 -0
  42. metadata +21 -26
  43. data/lib/rmtools/debug/present.rb +0 -39
  44. data/lib/rmtools/debug_notrace.rb +0 -2
  45. data/lib/rmtools/experimental/dumps.rb +0 -29
  46. data/lib/rmtools/experimental/numeric.rb +0 -54
  47. data/lib/rmtools/experimental/rails_backtrace.rb +0 -30
  48. data/lib/rmtools/experimental/string.rb +0 -56
  49. data/lib/rmtools/experimental/tree.rb +0 -72
  50. data/lib/rmtools/experimental.rb +0 -2
  51. data/lib/rmtools_nodebug.rb +0 -3
  52. data/lib/rmtools_notrace.rb +0 -7
  53. data/lib/rmtools_safe.rb +0 -2
@@ -0,0 +1,431 @@
1
+ RMTools::require 'text/string_scanner'
2
+
3
+ module RMTools
4
+ class CodeReader
5
+
6
+ module RE
7
+ leftop = '\[{(<=>~+\-*,;?:^&\|'
8
+ rightop = '\])}?!'
9
+ sname = '\w<=>~+\-*/\]\[\^%!?@&\|'
10
+ compname = "([\\.:#{sname}]+)"
11
+ name = "([#{sname}]+)"
12
+ mname = '([:\w]+)'
13
+ call_ = '(\{s*\||([\w?!)]|\.((\[\]|[<=>])?=[=~]?|[<>*\-+/%^&\|]+))[ \t]*\{)'
14
+ space = '[ \t]+'
15
+ space_ = '[ \t]*'
16
+ kw = 'if|elsif|else|unless|while|until|case|begin|rescue|when|then|or|and|not'
17
+ heredoc_handle = %q{<<(-)?(\w+|`[^`]+`|'[^']+'|"[^"]+")}
18
+ heredoc = %{([\\s#{leftop}]|[#{leftop}\\w!][ \t])\\s*#{heredoc_handle}}
19
+ re_sugar = %{(^|[#{leftop}\\n;]|\W!|\\b(#{kw})[ \t]|[\\w#{rightop}]/)\\s*/}
20
+ percent = '%([xwqrQW])?([\\/<({\[!\|])'
21
+ simple = [re_sugar, percent, '[#\'"`]']*'|'
22
+ mod_def = "module#{space+mname}"
23
+ class_def = "class(?:#{space_}(<<)#{space_}|#{space})([$@:\\w]+)(?:#{space_}<#{space_+mname})?"
24
+ method_def = "def#{space+compname}"
25
+ alias_def = "alias#{space}:?#{name+space}:?#{name}"
26
+
27
+ StringParseRE = /#{heredoc}|#{simple}|[{}]|[^\w#{rightop}'"`\/\\]\?\\?\S/m
28
+ HeredocParseRE = /\n|#{heredoc}|#{simple}/
29
+ StringRE = /(^['"`]$)|^#{percent}$/
30
+ RERE = %r{(?:^|[#{leftop}\\w!\\s/])\\s*(/)}
31
+ HeredocRE = heredoc_handle.to_re
32
+ Symbol = /^:#{name}$/
33
+ Attrs = /\s(c)?(?:attr_(reader|writer|accessor))#{space}((?::\w+#{space_},\s*)*:\w+)/
34
+ Include = /\s(include|extend)#{space+mname}/
35
+ AliasMethod = /\salias_method :#{name+space_},#{space_}:#{name}/
36
+ Beginners = /(([#{leftop}\n]?#{space_})(if|unless|while|until))#{
37
+ }|(.)?(?:(do|for)|begin|case)/
38
+ EOF = /($0\s*==\s*__FILE__\s*|__FILE__\s*==\s*\$0\s*)?\n/
39
+ BlockStart = /(?:^\{\s*\||.\{)$/
40
+ Ord = /^.\?\\?\S$/
41
+
42
+ MainParseRE = /#{simple
43
+ }|#{call_}|[{}]#{
44
+ }|(^|\n)=begin\b#{
45
+ }|^#{space_}[;\(]?#{space_}(#{mod_def}|#{method_def})#{
46
+ }|:#{name}#{
47
+ }|[^\w#{rightop}'"`\/\\]\?\\?\S#{
48
+ }|#{heredoc
49
+ }|(^|[#{leftop}\n])#{space_}((if|unless)\b|#{
50
+ }[;\(]?#{space_+class_def})#{
51
+ }|(^|[\n;])#{space_}(while|until)\b#{
52
+ }|(^|[#{leftop}\s])(do|case|begin|for)\b#{
53
+ }|\sc?(attr_(reader|writer|accessor))#{space}(:\w+#{space_},\s*)*:\w+?[\n;]#{
54
+ }|\salias_method :#{name+space_},#{space_}:#{name
55
+ }|\s(include|extend)#{space+mname
56
+ }|(^|[;\s])(#{alias_def}|end|__END__)\b/m
57
+
58
+ ModDef = mod_def.to_re
59
+ ClassDef = class_def.to_re
60
+ MethodDef = method_def.to_re
61
+ AliasDef = alias_def.to_re
62
+
63
+ Closers = {'<' => '>', '{' => '}', '[' => ']', '(' => ')'}
64
+ end
65
+
66
+
67
+ def initialize
68
+ @MethodCache = {'Object' => {}}
69
+ @ReadPaths = {}
70
+ end
71
+
72
+ def string(s, m)
73
+ return if m[1] and s.- == '$'
74
+ opener = m[1] || m[3] || m[5]
75
+ if opener == m[5]
76
+ closer = opener = m[5].tr('`\'"', '')
77
+ quote_re = /\\|\n#{'\s*' if m[4]}#{closer}/
78
+ else
79
+ closer = RE::Closers[opener] || opener
80
+ quote_re = /\\|#{Regexp.escape closer}/
81
+ end
82
+ openers_cnt = 1
83
+ curls_cnt = 0
84
+ backslash = false
85
+ quote_re |= /#\{/ if (m[5] and m[5].ord != ?') or closer =~ /[\/"`]/ or (m[2] =~ /[xrQW]/ or m[3])
86
+ instructions = [
87
+ [RE::Ord],
88
+ [/\s*#{Regexp.escape closer}$/, lambda {|s, m|
89
+ if backslash
90
+ backslash = false
91
+ break if s.- == '\\' and m[0] == closer
92
+ end
93
+ if (openers_cnt -= 1) == 0
94
+ throw :EOS
95
+ end
96
+ }],
97
+ [/\\/, lambda {|s, m|
98
+ prev = s.-
99
+ backslash = true
100
+ if prev == '\\'
101
+ i = 2
102
+ while prev == '\\'
103
+ prev = s.prev_in i
104
+ i += 1
105
+ backslash = !backslash
106
+ end
107
+ end
108
+ }],
109
+ [/\#\{/, lambda {|s, m|
110
+ if backslash
111
+ backslash = false
112
+ break if s.- == '\\'
113
+ end
114
+ curls_cnt += 1
115
+ catch(:inner_out) {s.each(RE::StringParseRE, [
116
+ [/^\#$/, lambda {|s, m| s.scan_until(/\n/)}],
117
+ [/^\{$/, lambda {|s, m| curls_cnt += 1}],
118
+ [/^\}$/, lambda {|s, m| throw :inner_out if (curls_cnt -= 1) == 0}],
119
+ [RE::HeredocRE, method(:heredoc)],
120
+ [RE::StringRE, method(:string)],
121
+ [RE::RERE, method(:string)]
122
+ ])}
123
+ }]
124
+ ]
125
+ if closer != opener
126
+ quote_re |= /#{Regexp.escape opener}/
127
+ instructions << [/#{Regexp.escape opener}$/, lambda {|s, m|
128
+ if backslash
129
+ backslash = false
130
+ break if s.- == '\\'
131
+ end
132
+ openers_cnt += 1
133
+ }]
134
+ end
135
+
136
+ catch(:EOS) {s.each(quote_re, instructions)}
137
+ end
138
+
139
+ def heredoc(s, m)
140
+ heredoc_list = [m[1..2]]
141
+ catch(:EOL) {s.each(RE::HeredocParseRE, [
142
+ [/[#\n]/, lambda {|s, m|
143
+ s.scan_until(/\n/) if m[0] == '#'
144
+ heredoc_list.each {|opener| string(s, [nil]*4+opener)}
145
+ throw :EOL
146
+ }],
147
+ [RE::HeredocRE, lambda {|s, m| heredoc_list << m[1..2]}],
148
+ [RE::StringRE, method(:string)],
149
+ [RE::RERE, method(:string)]
150
+ ])}
151
+ end
152
+
153
+ def parse_file(path)
154
+ @stack = []
155
+
156
+ if path.inline
157
+ return if @ReadPaths[path]
158
+ lines = get_lines(path)[0]
159
+ @ReadPaths[path] = true
160
+ else
161
+ lines = path.sharp_split(/\n/)
162
+ end
163
+ ss = StringScanner lines.join
164
+
165
+ curls_cnt = 0
166
+ catch(:EOF) {ss.each(RE::MainParseRE, [
167
+ [/^\#/, lambda {|s, m| s.scan_until(/\n/)}],
168
+
169
+ [RE::StringRE, method(:string)],
170
+
171
+ [/^\{$/, lambda {|s, m| curls_cnt += 1}],
172
+
173
+ [/^\}$/, lambda {|s, m|
174
+ if curls_cnt == 0
175
+ @stack.pop
176
+ else
177
+ curls_cnt -= 1
178
+ end
179
+ }],
180
+
181
+ [RE::Ord],
182
+
183
+ [RE::BlockStart, lambda {|s, m| @stack << [:block]}],
184
+
185
+ [RE::ModDef, lambda {|s, m|
186
+ @stack << [:mod, m[1]]
187
+ @MethodCache[clean_stack.lasts*'::'] = {}
188
+ }],
189
+
190
+ [RE::ClassDef, lambda {|s, m|
191
+ _stack = clean_stack
192
+ if _stack[-1] == [:block]
193
+ @stack << [:beginner]
194
+ break
195
+ elsif m[1]
196
+ if m[2] =~ /^[@$]/
197
+ @stack << [:beginner]
198
+ elsif _stack.any? and _stack[-1][0] == :def
199
+ @stack << [:beginner]
200
+ else
201
+ slf = _stack.lasts*'::'
202
+ name = m[2].sub 'self.', ''
203
+ name.sub! 'self', slf
204
+ name = fix_module_name slf, name
205
+ @stack << [:singleton, name]
206
+ end
207
+ else
208
+ new = clean_stack.lasts*'::'
209
+ @stack << [:class, m[2]]
210
+ name = fix_module_name new, m[3] if m[3]
211
+ new << '::' if new.b
212
+ new << m[2]
213
+ @MethodCache[new] ||= {}
214
+ inherit! new, name if m[3]
215
+ end
216
+ }],
217
+
218
+ [RE::MethodDef, lambda {|s, m|
219
+ _stack = clean_stack(true)
220
+ if _stack[-1] == [:block]
221
+ @stack << [:beginner]
222
+ break
223
+ end
224
+ start = s.pos - s.matched[/[^\n]+$/].size
225
+ name = m[1].sub(/::([^:.]+)$/, '.\1')
226
+ name.sub!(/#{_stack.last[1]}\./, 'self.') if _stack.any?
227
+ if name[/^self\.(.+)/]
228
+ @stack << [:def, "#{_stack.lasts*'::'}.#$1", start]
229
+ elsif name['.'] and name =~ /^[A-Z]/
230
+ mod, name = name/'.'
231
+ fix_module_name(_stack.lasts*'::', mod) >> '.' >> name
232
+ @stack << [:def, name, start]
233
+ else
234
+ prefix = (_stack.any? && _stack[-1][0] == :singleton) ? _stack[-1][1]+'.' : _stack.lasts*'::'+'#'
235
+ @stack << [:def, prefix+name, start]
236
+ end
237
+ }],
238
+
239
+ [RE::AliasDef, lambda {|s, m|
240
+ _stack = clean_stack
241
+ case _stack.any? && _stack[-1][0]
242
+ when false, :def, :block
243
+ break
244
+ when :singleton
245
+ prefix = _stack[-1][1]
246
+ new, old = '.'+m[1], '.'+m[2]
247
+ else
248
+ prefix = _stack.lasts*'::'
249
+ new, old = '#'+m[1], '#'+m[2]
250
+ end
251
+ @MethodCache[prefix][new] = @MethodCache[prefix][old] || "def #{new}(*args)\n #{old}(*args)\nend"
252
+ }],
253
+
254
+ [RE::Symbol],
255
+
256
+ [RE::RERE, method(:string)],
257
+
258
+ [RE::HeredocRE, method(:heredoc)],
259
+
260
+ [/(^|\n)=begin/, lambda {|s, m| s.scan_until(/\n=end\s*\n/)}],
261
+
262
+ [RE::Attrs, lambda {|s, m|
263
+ _stack = clean_stack
264
+ if _stack[-1][0] == :class
265
+ prefix = _stack.lasts*'::'
266
+ attrs = (m[3]/',').map {|attr| (m[1] ? '.' : '#')+attr.strip[1..-1]}
267
+ if m[2].in %w(reader accessor)
268
+ attrs.each {|attr| (@MethodCache[prefix][attr] ||= []) << "def #{'self.' if m[1]}#{attr}\n #{'@' if m[1]}@#{attr}\nend"}
269
+ end
270
+ if m[2].in %w(writer accessor)
271
+ attrs.each {|attr| (@MethodCache[prefix][attr] ||= []) << "def #{'self.' if m[1]}#{attr}=value\n #{'@' if m[1]}@#{attr} = value\nend"}
272
+ end
273
+ end
274
+ }],
275
+
276
+ [RE::Include, lambda {|s, m|
277
+ _stack = clean_stack
278
+ if _stack.empty?
279
+ if m[1] == 'include'
280
+ inherit! 'Object', m[2]
281
+ else
282
+ inherit_singletons! 'Object', m[2]
283
+ end
284
+ elsif !_stack[-1][0].in([:def, :block]) and m[2] =~ /^[A-Z]/
285
+ if m[1] == 'include'
286
+ inherit! _stack.lasts*'::', m[2]
287
+ else
288
+ inherit_singletons! _stack.lasts*'::', m[2]
289
+ end
290
+ end
291
+ }],
292
+
293
+ [RE::AliasMethod, lambda {|s, m|
294
+ _stack = clean_stack
295
+ if _stack[-1][0] == :class
296
+ new, old = m[1..2]
297
+ prefix = _stack.lasts*'::'
298
+ @MethodCache[prefix][new] = @MethodCache[prefix][old] || "def #{new}(*args)\n #{old}(*args)\nend"
299
+ end
300
+ }],
301
+
302
+ [RE::Beginners, lambda {|s, m|
303
+ if (m[2] and s.last != 0 and m[2].tr(' \t', '').empty? and !(s.string[s.last-1,1].to_s)[/[\n;]/])
304
+ else
305
+ if m[3] == 'if' and @stack.empty? and s.check_until(RE::EOF) and s.matched != "\n"
306
+ throw :EOF
307
+ end
308
+ @stack << [m[5] ? :block : :beginner]
309
+ end
310
+ }],
311
+
312
+ [/(^|[\s;])end/, lambda {|s, m|
313
+ exit = @stack.pop
314
+ case exit[0]
315
+ when :def
316
+ prefix, name = exit[1].sharp_split(/[.@#]/, 2)
317
+ if !name
318
+ prefix, name = 'Object', prefix
319
+ end
320
+ if @MethodCache[prefix]
321
+ (@MethodCache[prefix][name] ||= []) << (path.inline ? [path, exit[2]...s.pos] : s.string[exit[2]...s.pos])
322
+ end
323
+ end
324
+ }],
325
+
326
+ [/(^|[\s;])__END__/, lambda {|s, m| throw :EOF}]
327
+ ])}
328
+ ss
329
+ end
330
+
331
+ def clean_stack(no_def=false)
332
+ @stack.select {|e| e[0] != :beginner and !no_def || e[0] != :def}
333
+ end
334
+
335
+ def inherit!(descendant, ancestor)
336
+ @MethodCache[descendant].reverse_merge((
337
+ @MethodCache[fix_module_name(descendant, ancestor)] ||= {}
338
+ ).map_values {|defs| defs.dup})
339
+ end
340
+
341
+ def inherit_singletons!(descendant, ancestor)
342
+ (@MethodCache[fix_module_name(descendant, ancestor)] ||= {}).each {|name, defs|
343
+ @MethodCache[descendant][name.sub('#', '.')] = defs.dup if name.ord == ?#
344
+ }
345
+ end
346
+
347
+ def fix_module_name(current, name)
348
+ if name =~ /^::/ or current == ''
349
+ current+name
350
+ elsif name == current or name == 'self'
351
+ current
352
+ elsif name !~ /^[A-Z]/
353
+ current+'#'+name
354
+ else
355
+ path = current+'::'+name
356
+ if @MethodCache[path]
357
+ path
358
+ else
359
+ @MethodCache[name] ||= {}
360
+ name
361
+ end
362
+ end
363
+ end
364
+
365
+ def get_lines(path)
366
+ SCRIPT_LINES__.select {|d, f| d[path]}.lasts
367
+ end
368
+
369
+ def print_lines(prefix, name, all)
370
+ map = lambda {|lines|
371
+ if lines.is Array
372
+ lines = SCRIPT_LINES__[lines[0]].join[lines[1]]
373
+ end
374
+ lines }
375
+ methods = all ? @MethodCache[prefix][name].map(&map) : map.call(@MethodCache[prefix][name].last)
376
+ puts methods
377
+ end
378
+
379
+ def code_of(path, name=nil, all=false)
380
+ if name.in [true, :all]
381
+ all = true
382
+ end
383
+ if path.is String
384
+ prefix, name = path.sharp_split(/[.#]/, 2)
385
+ elsif Class === path
386
+ prefix = path.name
387
+ name = ".#{name}"
388
+ else
389
+ prefix = path.class.name
390
+ name = "##{name}"
391
+ end
392
+ if !(@MethodCache[prefix]||{})[name]
393
+ puts "looking up script lines, please wait..."
394
+ SCRIPT_LINES__.each_key {|k| parse_file k
395
+ break if (@MethodCache[prefix]||{})[name]
396
+ }
397
+ end
398
+ if !(@MethodCache[prefix]||{})[name]
399
+ print "nothing was found for #{prefix}#{name}"
400
+ name = name.tr('#.', '.#')
401
+ if (@MethodCache[prefix]||{})[name]
402
+ puts ", but found for #{name}:"
403
+ print_lines prefix, name, all
404
+ else
405
+ return puts ''
406
+ end
407
+ end
408
+ puts "code for #{prefix}#{name}:"
409
+ print_lines prefix, name, all
410
+ end
411
+
412
+ end
413
+
414
+ Reader = CodeReader.new
415
+ end
416
+
417
+ module Kernel
418
+
419
+ def code_of(*args)
420
+ RMTools::Reader.code_of(*args)
421
+ end
422
+
423
+ end
424
+
425
+ class Method
426
+
427
+ def code(all=false)
428
+ RMTools::Reader.code_of(receiver, name, all)
429
+ end
430
+
431
+ end
@@ -5,11 +5,11 @@ module RMTools
5
5
 
6
6
  def highlighted_line(file, line)
7
7
  if defined? SCRIPT_LINES__ and SCRIPT_LINES__[file]
8
- " >> #{Painter.green SCRIPT_LINES__[file][line.to_i - 1].chop}"
8
+ " >> #{Painter.green((SCRIPT_LINES__[file][line.to_i - 1] || "<line #{line} is not found> ").chop)}"
9
9
  else
10
10
  file = Readline::TEMPLOG if file == '(irb)' and defined? Readline::TEMPLOG
11
11
  if File.file? file
12
- line_read = read_lines(file, line.to_i)
12
+ line_read = read_lines(file, line.to_i) || "<line #{line} is not found> "
13
13
  if defined? SCRIPT_LINES__
14
14
  SCRIPT_LINES__[file] = IO.readlines(file)
15
15
  highlighted_line file, line
@@ -13,17 +13,18 @@ module RMTools
13
13
  attr_reader :default_format
14
14
 
15
15
  Modes = [:debug, :log, :info, :warn]
16
- NOPRINT = 4
17
- NOLOG = 2
16
+ NOPRINT = 8
17
+ NOLOG = 4
18
+ PREV_CALLER = 2
18
19
  INLINE = 1
19
20
 
20
21
  def initialize format={}
21
- @clr = Coloring.new
22
+ @c = Painter
22
23
  @highlight = {
23
- :warn => @clr.red_bold("WARN"),
24
- :log => @clr.cyan("INFO"),
25
- :info => @clr.cyan_bold("INFO"),
26
- :debug => @clr.gray_bold("DEBUG")
24
+ :warn => @c.red_bold("WARN"),
25
+ :log => @c.cyan("INFO"),
26
+ :info => @c.cyan_bold("INFO"),
27
+ :debug => @c.gray_bold("DEBUG")
27
28
  }
28
29
  @file_formats = Hash.new(@default_format = {})
29
30
  set_format :global, format
@@ -45,7 +46,7 @@ module RMTools
45
46
  puts %{ :q => false, # not print
46
47
  :out => false, # output to file, may have strftime's %H%M%Y for filename
47
48
  :time => ["%H:%M:%S", "%03d"], # strftime, [msecs]
48
- :caller => "#{@clr.gray('%f:%l')} #{@clr.red_bold(':%m')}", # file:line :method
49
+ :caller => "#{@c.gray('%f:%l')} #{@c.red_bold(':%m')}", # file:line :method
49
50
  :format => "%time %mode [%caller]: %text" # no comments}
50
51
  end
51
52
 
@@ -53,7 +54,7 @@ module RMTools
53
54
  def set_format *args
54
55
  global, format = args.fetch_opts [nil],
55
56
  :time => ["%H:%M:%S", "%03d"],
56
- :caller => "#{@clr.gray('%f:%l')} #{@clr.red_bold(':%m')}",
57
+ :caller => "#{@c.gray('%f:%l')} #{@c.red_bold(':%m')}",
57
58
  :format => "%time %mode [%caller]: %text"
58
59
  if global
59
60
  _set_format @default_format, format
@@ -94,17 +95,13 @@ module RMTools
94
95
  if caler
95
96
  str.sub! "%caller", caler.sub(String::CALLER_RE, cfg.cf)
96
97
  end
97
- log_str = @clr.clean str
98
+ log_str = @c.clean str
98
99
  RMTools.write out, log_str if log_
99
100
  Kernel.print str if print_
100
101
  end
101
-
102
- def check_binding a
103
- a[0].is(Binding) ? [a[0], a[1] || 0] : [nil, a[0] || 0]
104
- end
105
102
 
106
103
  def get_config!
107
- @file_formats.empty? ? @default_format : @file_formats[File.expand_path(caller(2)[0].till ':')]
104
+ @file_formats.empty? ? @default_format : @file_formats[File.expand_path((@current_caller = caller)[1].till ':')]
108
105
  end
109
106
 
110
107
  # controllers:
@@ -115,62 +112,62 @@ module RMTools
115
112
  # this messages regardless of any globals
116
113
  # - @out_all: write to file any messages
117
114
 
118
- def warn text="\b\b ", *a
115
+ def warn *args
119
116
  cfg = get_config!
120
117
  if (cfg.out or cfg.print) && !@mute_warn
121
- bind, opts = check_binding a
122
- opts |= NOLOG if !cfg.out
123
- opts |= NOPRINT if !cfg.print
124
- text = yield if block_given?
125
- _print(:warn, text, opts, cfg._caller && caller[0], bind, cfg)
118
+ text, bind, opts = args.get_opts [!block_given? && args[0].is(Hash) ? args[0] : "\b\b ", nil], :mute => 0
119
+ opts[:mute] |= NOLOG if !cfg.out
120
+ opts[:mute] |= NOPRINT if !cfg.print
121
+ return if block_given? && (text = yield).nil?
122
+ _print(:warn, text, opts[:mute], cfg._caller && (@current_caller || caller)[opts[:caller].to_i], bind, cfg)
126
123
  end
127
124
  end
128
125
 
129
- def log text="\b\b ", *a
126
+ def log *args
130
127
  cfg = get_config!
131
128
  if (cfg.out or cfg.print && !$quiet && $verbose) && !@mute_log
132
- bind, opts = check_binding a
133
- opts |= NOLOG if !cfg.out
134
- opts |= NOPRINT if !(cfg.print && !$quiet && $verbose)
135
- text = yield if block_given?
136
- _print(:log, text, opts, cfg._caller && caller[0], bind, cfg)
129
+ text, bind, opts = args.get_opts [!block_given? && args[0].is(Hash) ? args[0] : "\b\b ", nil], :mute => 0
130
+ opts[:mute] |= NOLOG if !cfg.out
131
+ opts[:mute] |= NOPRINT if !(cfg.print && !$quiet && $verbose)
132
+ return if block_given? && (text = yield).nil?
133
+ _print(:log, text, opts[:mute], cfg._caller && (@current_caller || caller)[opts[:caller].to_i], bind, cfg)
137
134
  end
138
135
  end
139
136
 
140
- def info text="\b\b ", *a
137
+ def info *args
141
138
  cfg = get_config!
142
139
  if (cfg.print && !$quiet or cfg.out && cfg.out_all) && !@mute_info
143
- bind, opts = check_binding a
144
- opts |= NOLOG if !(cfg.out && cfg.out_all)
145
- opts |= NOPRINT if !(cfg.print && !$quiet)
146
- text = yield if block_given?
147
- _print(:info, text, opts, cfg._caller && caller[0], bind, cfg)
140
+ text, bind, opts = args.get_opts [!block_given? && args[0].is(Hash) ? args[0] : "\b\b ", nil], :mute => 0
141
+ opts[:mute] |= NOLOG if !(cfg.out && cfg.out_all)
142
+ opts[:mute] |= NOPRINT if !(cfg.print && !$quiet)
143
+ return if block_given? && (text = yield).nil?
144
+ _print(:info, text, opts[:mute], cfg._caller && (@current_caller || caller)[opts[:caller].to_i], bind, cfg)
148
145
  end
149
146
  end
150
147
 
151
- def debug text="\b\b ", *a
148
+ def debug *args
152
149
  cfg = get_config!
153
150
  if (cfg.print && $panic && !$quiet or cfg.out && cfg.out_all) && !@mute_debug
154
- bind, opts = check_binding a
155
- opts |= NOLOG if !(cfg.out && cfg.out_all)
156
- opts |= NOPRINT if !(cfg.print && $panic && !$quiet)
157
- text = yield if block_given?
158
- _print(:debug, text, opts, cfg._caller && caller[0], bind, cfg)
151
+ text, bind, opts = args.get_opts [!block_given? && args[0].is(Hash) ? args[0] : "\b\b ", nil], :mute => 0
152
+ opts[:mute] |= NOLOG if !(cfg.out && cfg.out_all)
153
+ opts[:mute] |= NOPRINT if !(cfg.print && $panic && !$quiet)
154
+ return if block_given? && (text = yield).nil?
155
+ _print(:debug, text, opts[:mute], cfg._caller && (@current_caller || caller)[opts[:caller].to_i], bind, cfg)
159
156
  end
160
157
  end
161
158
 
159
+ alias <= debug
162
160
  alias << info
163
161
  alias < warn
164
162
 
165
163
  Modes.each {|m| define_method("#{m}=") {|mute| send :"mute_#{m}=", !mute}}
166
-
167
- def outall=(x) @default_format.out_all = x end
168
- def print=(x) @default_format.print = x end
169
- def out=(x) @default_format.out = x end
170
-
171
- def out_all() @default_format.out_all end
172
- def print() @default_format.print end
173
- def out() @default_format.out end
164
+
165
+ %w(out_all print out).each {|m|
166
+ define_method m do @default_format.__send__ m.to_sym
167
+ end
168
+ define_method m+'=' do |x| @default_format.__send__ :"#{m}=", x
169
+ end
170
+ }
174
171
 
175
172
  def inspect() get_format end
176
173
 
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- RMTools::require 'debug/binding'
2
+ RMTools::require 'dev/binding'
3
3
  require 'active_support/core_ext/class'
4
4
 
5
5
  module RMTools
@@ -16,7 +16,10 @@ module RMTools
16
16
 
17
17
  @@binding_stack = []
18
18
  DefaultRescue = lambda {|e|
19
+ stop
19
20
  @@binding_stack.inspect_envs.present
21
+ require 'irb'
22
+ IRB.start('/usr/bin/irb18')
20
23
  @@binding_stack.last.start_interaction
21
24
  raise e
22
25
  }
@@ -35,7 +38,7 @@ module RMTools
35
38
  end
36
39
 
37
40
  def self.update_ignore
38
- @@ignore_path = %r{(/usr/lib/ruby/(1.8/|gems/1.8/gems/#{
41
+ @@ignore_path = %r{^(/usr/lib/ruby/(1.8/|gems/1.8/(bundler/)?gems/#{
39
42
  "(#{@@ignore_gems*'|'})" if !@@ignore_all_gems and @@ignore_gems
40
43
  })#{
41
44
  "|(#{@@ignore_names*'|'})" if @@ignore_names.b
@@ -61,6 +64,8 @@ module RMTools
61
64
  end
62
65
 
63
66
  def self.catch(rescue_proc=DefaultRescue)
67
+ update_ignore
68
+ start
64
69
  begin yield
65
70
  rescue => e
66
71
  @@keep_binding_stack = false
@@ -70,6 +75,7 @@ module RMTools
70
75
  @@binding_stack.clear
71
76
  end
72
77
  end
78
+ stop
73
79
  end
74
80
 
75
81
  def self.stop