rmtools 1.1.11 → 1.2.0

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.
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