rmtools 1.0.0 → 1.1.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 (110) hide show
  1. data/History.txt +5 -0
  2. data/Manifest.txt +84 -26
  3. data/Rakefile +7 -4
  4. data/ext/extconf.rb +1 -1
  5. data/ext/rmtools.cpp +27 -12
  6. data/ext/rmtools.h +6 -5
  7. data/lib/rmtools/b.rb +18 -0
  8. data/lib/rmtools/console/coloring.rb +72 -0
  9. data/lib/rmtools/console/highlight.rb +13 -0
  10. data/lib/rmtools/{printing.rb → console/printing.rb} +17 -2
  11. data/lib/rmtools/console.rb +1 -0
  12. data/lib/rmtools/conversions/enum.rb +23 -0
  13. data/lib/rmtools/conversions/int.rb +47 -0
  14. data/lib/rmtools/conversions/string.rb +26 -0
  15. data/lib/rmtools/conversions.rb +1 -0
  16. data/lib/rmtools/core/arguments.rb +52 -0
  17. data/lib/rmtools/{boolean.rb → core/boolean.rb} +0 -13
  18. data/lib/rmtools/core/class.rb +41 -0
  19. data/lib/rmtools/core/js.rb +45 -0
  20. data/lib/rmtools/core/kernel.rb +28 -0
  21. data/lib/rmtools/{module.rb → core/module.rb} +0 -41
  22. data/lib/rmtools/core/numeric.rb +35 -0
  23. data/lib/rmtools/{object.rb → core/object.rb} +2 -23
  24. data/lib/rmtools/core/proc.rb +18 -0
  25. data/lib/rmtools/core/regexp.rb +11 -0
  26. data/lib/rmtools/core/string_compliance.rb +31 -0
  27. data/lib/rmtools/core.rb +1 -0
  28. data/lib/rmtools/db/active_record.rb +54 -0
  29. data/lib/rmtools/db.rb +7 -0
  30. data/lib/rmtools/debug/binding.rb +56 -0
  31. data/lib/rmtools/debug/highlight.rb +23 -0
  32. data/lib/rmtools/debug/logging.rb +176 -0
  33. data/lib/rmtools/debug/present.rb +38 -0
  34. data/lib/rmtools/debug/timer.rb +19 -0
  35. data/lib/rmtools/debug/traceback.rb +92 -0
  36. data/lib/rmtools/debug.rb +1 -0
  37. data/lib/rmtools/debug_notrace.rb +1 -0
  38. data/lib/rmtools/enumerable/array.rb +134 -0
  39. data/lib/rmtools/enumerable/array_iterators.rb +33 -0
  40. data/lib/rmtools/enumerable/common.rb +49 -0
  41. data/lib/rmtools/{hash.rb → enumerable/hash.rb} +8 -8
  42. data/lib/rmtools/enumerable/object_space.rb +19 -0
  43. data/lib/rmtools/enumerable/range.rb +201 -0
  44. data/lib/rmtools/enumerable.rb +1 -0
  45. data/lib/rmtools/experimental/blackhole.rb +12 -0
  46. data/lib/rmtools/experimental/deprecation.rb +36 -0
  47. data/lib/rmtools/experimental/dumps.rb +28 -0
  48. data/lib/rmtools/{numeric.rb → experimental/numeric.rb} +22 -51
  49. data/lib/rmtools/experimental/rails_backtrace.rb +29 -0
  50. data/lib/rmtools/experimental/string.rb +56 -0
  51. data/lib/rmtools/{tree.rb → experimental/tree.rb} +0 -0
  52. data/lib/rmtools/experimental.rb +1 -0
  53. data/lib/rmtools/fs/dir.rb +89 -0
  54. data/lib/rmtools/fs/file.rb +104 -0
  55. data/lib/rmtools/fs/io.rb +58 -0
  56. data/lib/rmtools/fs/tools.rb +49 -0
  57. data/lib/rmtools/fs.rb +1 -0
  58. data/lib/rmtools/functional/fold.rb +32 -0
  59. data/lib/rmtools/{string_to_proc.rb → functional/string_to_proc.rb} +2 -22
  60. data/lib/rmtools/functional/unfold.rb +16 -0
  61. data/lib/rmtools/functional.rb +1 -0
  62. data/lib/rmtools/ip/numeric.rb +35 -0
  63. data/lib/rmtools/ip/string.rb +45 -0
  64. data/lib/rmtools/ip.rb +1 -0
  65. data/lib/rmtools/lang/ansi.rb +17 -0
  66. data/lib/rmtools/lang/cyrillic.rb +106 -0
  67. data/lib/rmtools/lang/regexp.rb +8 -0
  68. data/lib/rmtools/lang/shortcuts.rb +20 -0
  69. data/lib/rmtools/lang.rb +1 -0
  70. data/lib/rmtools/rand/array.rb +39 -0
  71. data/lib/rmtools/rand/enum.rb +26 -0
  72. data/lib/rmtools/rand/range.rb +13 -0
  73. data/lib/rmtools/{random.rb → rand/string.rb} +13 -107
  74. data/lib/rmtools/rand.rb +1 -0
  75. data/lib/rmtools/require.rb +13 -0
  76. data/lib/rmtools/setup.rb +6 -5
  77. data/lib/rmtools/text/string_parse.rb +60 -0
  78. data/lib/rmtools/{stringscanner.rb → text/string_scanner.rb} +3 -2
  79. data/lib/rmtools/text/string_simple.rb +75 -0
  80. data/lib/rmtools/text/string_split.rb +148 -0
  81. data/lib/rmtools/text/textilize.rb +44 -0
  82. data/lib/rmtools/text.rb +1 -0
  83. data/lib/rmtools/time/global.rb +17 -0
  84. data/lib/rmtools/time/russian.rb +47 -0
  85. data/lib/rmtools/time.rb +1 -32
  86. data/lib/rmtools/xml/document.rb +28 -0
  87. data/lib/rmtools/xml/finders.rb +84 -0
  88. data/lib/rmtools/xml/libxml.rb +11 -0
  89. data/lib/rmtools/xml/node.rb +196 -0
  90. data/lib/rmtools/xml/string.rb +43 -0
  91. data/lib/rmtools/xml/xpath.rb +32 -0
  92. data/lib/rmtools/xml.rb +7 -0
  93. data/lib/rmtools.rb +8 -44
  94. metadata +97 -72
  95. data/lib/rmtools/arguments.rb +0 -24
  96. data/lib/rmtools/array.rb +0 -189
  97. data/lib/rmtools/binding.rb +0 -23
  98. data/lib/rmtools/coloring.rb +0 -82
  99. data/lib/rmtools/cyr-time.rb +0 -49
  100. data/lib/rmtools/cyrilic.rb +0 -124
  101. data/lib/rmtools/dumps.rb +0 -192
  102. data/lib/rmtools/enum.rb +0 -90
  103. data/lib/rmtools/io.rb +0 -303
  104. data/lib/rmtools/js.rb +0 -25
  105. data/lib/rmtools/limited_string.rb +0 -17
  106. data/lib/rmtools/logging.rb +0 -158
  107. data/lib/rmtools/proc.rb +0 -25
  108. data/lib/rmtools/range.rb +0 -100
  109. data/lib/rmtools/string.rb +0 -276
  110. data/lib/rmtools/traceback.rb +0 -106
@@ -0,0 +1,28 @@
1
+ module Kernel
2
+
3
+ # re-require
4
+ def require!(file)
5
+ %w{.rb .so .dll}.each {|ext| $".delete "#{file}#{ext}"}
6
+ require file
7
+ end
8
+
9
+ def obtained(obj, &func)
10
+ if obj.is Proc
11
+ if obj.arity == 0
12
+ func.call obj.call
13
+ else # obj is a function receiving another function
14
+ obj.call &func
15
+ end
16
+ else func.call obj
17
+ end
18
+ end
19
+
20
+ def TypeError! given, *expected
21
+ "invalid argument type #{given.class.name}, expected #{expected*' or '}"
22
+ end
23
+
24
+ def executing? file=$0
25
+ caller(0)[0] =~ /^#{file}:/
26
+ end
27
+
28
+ end
@@ -70,44 +70,3 @@ private
70
70
 
71
71
  end
72
72
 
73
- class Class
74
-
75
- # define python-like initializer form
76
- def __init__
77
- modname, classname = name.rsplit('::', 2)
78
- classname ||= modname
79
- mod = '::'.in(name) ? eval(modname) : RMTools
80
- mod.module_eval "def #{classname} *args; #{name}.new *args end
81
- module_function :#{classname}"
82
- if mod != RMTools
83
- mod.each_child {|c| c.class_eval "include #{mod}; extend #{mod}" if !c.in c.children}
84
- end
85
- end
86
-
87
- def method_proxy *vars
88
- buffered_missing = instance_methods.grep(/method_missing/).sort.last || 'method_missing'
89
- # next arg overrides previous
90
- vars.each {|v|
91
- class_eval "
92
- alias #{buffered_missing.bump! '_'} method_missing
93
- def method_missing *args, &block
94
- #{v}.send *args, &block
95
- rescue NoMethodError
96
- #{buffered_missing} *args, &block
97
- end"
98
- }
99
- end
100
-
101
- def personal_methods filter=//
102
- (self.singleton_methods - self.superclass.singleton_methods).sort!.grep(filter)
103
- end
104
-
105
- def my_instance_methods filter=//
106
- (self.public_instance_methods - Object.public_instance_methods).sort!.grep(filter)
107
- end
108
-
109
- def personal_instance_methods filter=//
110
- (self.public_instance_methods - self.superclass.public_instance_methods).sort!.grep(filter)
111
- end
112
-
113
- end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ class Numeric
3
+
4
+ def ceil_to(i)
5
+ self + i - self%i
6
+ end
7
+
8
+ def floor_to(i)
9
+ self - self%i
10
+ end
11
+
12
+ def round_to(i)
13
+ [ceil_to(i), floor_to(i)].max
14
+ end
15
+
16
+ def between(min, max)
17
+ min < self and self < max
18
+ end
19
+
20
+ def mult_of(subj)
21
+ self%subj == 0
22
+ end
23
+
24
+ def hex
25
+ sprintf "%x", self
26
+ end
27
+
28
+ end
29
+
30
+ module Math
31
+
32
+ def logb(b, x) log(x)/log(b) end
33
+
34
+ end
35
+
@@ -1,11 +1,7 @@
1
1
  # encoding: utf-8
2
2
  class Object
3
3
  alias :resto :respond_to?
4
-
5
- def requrie file
6
- require file
7
- end
8
- #alias :requrie :require # most frequent typo, lol
4
+ alias :requrie :require # most frequent typo, lol
9
5
 
10
6
  def is klass
11
7
  if Array === klass
@@ -50,25 +46,8 @@ class Object
50
46
  self
51
47
  end
52
48
 
53
- def in *container
49
+ def in(*container)
54
50
  container.size == 1 ? container[0].include?(self) : container.include?(self)
55
51
  end
56
52
 
57
- def require! file
58
- %w{.rb .so .dll}.each {|ext| $".delete "#{file}#{ext}"}
59
- require file
60
- end
61
-
62
- def b; self end
63
-
64
- end
65
-
66
- class BlackHole
67
-
68
- # Think twice before use it. It may devour your code!
69
- def method_missing *args
70
- BlackHole.new
71
- end
72
-
73
53
  end
74
-
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ class Proc
3
+ NULL = lambda {} unless defined? Proc::NULL
4
+ attr_accessor :string
5
+
6
+ def when
7
+ Thread.new do
8
+ sleep 0.001 until yield
9
+ call
10
+ end
11
+ end
12
+
13
+ def self.eval string, binding=nil
14
+ (proc = (binding || Kernel).eval "lambda {#{string}}").string = string
15
+ proc
16
+ end
17
+
18
+ end
@@ -0,0 +1,11 @@
1
+ class Regexp
2
+
3
+ def | re
4
+ Regexp.new(source+'|'+re.source, options | re.options)
5
+ end
6
+
7
+ def in string
8
+ string =~ self
9
+ end
10
+
11
+ end
@@ -0,0 +1,31 @@
1
+ class String
2
+
3
+ if RUBY_VERSION < "1.9"
4
+ def ord; self[0] end
5
+ else
6
+ # BUGFIX?
7
+ alias :sub19 :sub
8
+ alias :sub19! :sub!
9
+ alias :gsub19 :gsub
10
+ alias :gsub19! :gsub!
11
+
12
+ def sub! a,b=nil,&c
13
+ if b
14
+ if b=~/\\\d/
15
+ b = b.sub19!(/\\\d/) {|m| "\#{$#{m[1,1]}}"}
16
+ sub19!(a) {eval "\"#{b}\""}
17
+ else sub19!(a) {b} end
18
+ else sub19! a,&c end
19
+ end
20
+
21
+ def sub a,b=nil,&c
22
+ if b
23
+ if b=~/\\\d/
24
+ b = b.sub19(/\\\d/) {|m| "\#{$#{m[1,1]}}"}
25
+ sub19(a) {eval "\"#{b}\""}
26
+ else sub19(a) {b} end
27
+ else sub19 a,&c end
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1 @@
1
+ require_with_path __FILE__, '*'
@@ -0,0 +1,54 @@
1
+ require 'active_record'
2
+
3
+ module ActiveRecord
4
+
5
+ def self.establish_connection_with config
6
+ c = case config
7
+ when String
8
+ c = if config.inline
9
+ if c = RMTools.read(config) then c
10
+ else return; nil
11
+ end
12
+ else config
13
+ end
14
+ YAML.load c
15
+ when IO then YAML.load config
16
+ else config
17
+ end
18
+ Base.establish_connection(c) rescue(false)
19
+ end
20
+
21
+ class Base
22
+
23
+ def self.establish_connection_with config
24
+ ActiveRecord.establish_connection_with config
25
+ end
26
+
27
+ def to_hash
28
+ serializer = Serializer.new(self)
29
+ serializer.respond_to?(:attributes_hash) ?
30
+ serializer.attributes_hash :
31
+ serializer.serializable_record
32
+ end
33
+
34
+ alias :delete_with_id :delete
35
+ # a problem was: model.delete() won't work if it has no id. Just delete() it if has
36
+ def delete
37
+ id ? delete_with_id : self.class.delete_all(attributes)
38
+ end
39
+
40
+ def self.merge_conditions(*conditions)
41
+ segments = conditions.map {|condition|
42
+ sanitize_sql condition
43
+ }.reject {|condition|
44
+ condition.blank?
45
+ }
46
+ "(#{segments.join(') AND (')})" unless segments.empty?
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+
53
+
54
+
data/lib/rmtools/db.rb ADDED
@@ -0,0 +1,7 @@
1
+ begin
2
+ require 'active_record'
3
+ ActiveRecord::Base
4
+ require_with_path __FILE__, 'active_record'
5
+ rescue
6
+ nil
7
+ end
@@ -0,0 +1,56 @@
1
+ class Binding
2
+
3
+ def inspect_local_variables
4
+ vars = self.eval('local_variables') # ['a', 'b']
5
+ values = self.eval "[#{vars * ','}]" # ["a's value", "b's value"]
6
+ Hash[vars.zip(values)]
7
+ end
8
+
9
+ def inspect_instance_variables
10
+ vars = self.eval('instance_variables') # ['@a', '@b']
11
+ values = self.eval "[#{vars * ','}]" # ["@a's value", "@b's value"]
12
+ Hash[vars.zip(values)]
13
+ end
14
+
15
+ def inspect_env
16
+ self.eval("{'self' => self}").merge(inspect_local_variables).merge(inspect_instance_variables)
17
+ end
18
+
19
+ def valid_types(pattern_ary)
20
+ self.eval("[#{self.eval('local_variables')*','}]").valid_types(pattern_ary)
21
+ end
22
+
23
+ def report(obj)
24
+ if Array === obj
25
+ obj.map {|s| self.eval "\"#{s.gsub('"'){'\"'}} = \#{(#{s}).inspect}\""} * '; '
26
+ else
27
+ obj.to_s.split(' ').map {|s| self.eval "\"#{s.gsub('"'){'\"'}} = \#{(#{s}).inspect}\""} * '; '
28
+ end
29
+ end
30
+
31
+ # it's supposed to be called during TDD in an IRB session
32
+ # $__MAIN__ must be `self' or root IRB session, i.e. `main' object
33
+ # def tested_function
34
+ # blah blah blah
35
+ # rescue => err
36
+ # binding.start_interaction
37
+ # raise err
38
+ # end
39
+ def start_interaction(sandbox=true)
40
+ $__env__ = inspect_env
41
+ Kernel.puts RMTools.format_trace(caller(2)).join("\n")
42
+ $env.present
43
+ $__binding__ = self
44
+
45
+ $log << "entering irb"
46
+ $__MAIN__.irb
47
+ # Now input "irb_change_binding$__binding__" and have fun with debug
48
+ $log << "exiting irb"
49
+
50
+ if sandbox
51
+ self.eval($env.keys.map {|k, v| "#{k} = $env[#{k.inspect}]"} * '; ')
52
+ end
53
+ $__env__ = nil
54
+ end
55
+
56
+ end
@@ -0,0 +1,23 @@
1
+ require_with_path 'console/coloring'
2
+
3
+ module RMTools
4
+
5
+ def highlighted_line(file, line)
6
+ if defined? SCRIPT_LINES__
7
+ " >> #{Painter.green SCRIPT_LINES__[file][line.to_i - 1].chop}" if SCRIPT_LINES__[file]
8
+ else
9
+ file = Readline::TEMPLOG if file == '(irb)' and defined? Readline::TEMPLOG
10
+ " >> #{Painter.green read_lines(file, line.to_i).chop}" if File.file? file
11
+ end
12
+ end
13
+
14
+ module_function :highlighted_line
15
+ end
16
+
17
+ class Proc
18
+
19
+ def inspect
20
+ "#{str=to_s}: #{@string ? Painter.green(@string) : "\n"+RMTools.highlighted_line(*str.match(/([^@]+):(\d+)>$/)[1..2])}"
21
+ end
22
+
23
+ end
@@ -0,0 +1,176 @@
1
+ # encoding: utf-8
2
+ require_with_path 'console/coloring'
3
+ require_with_path 'text/string_parse'
4
+
5
+ module RMTools
6
+
7
+ # lazy logger
8
+ # with caller processing and highlighting
9
+ class RMLogger
10
+ __init__
11
+ attr_accessor :mute_info, :mute_warn, :mute_log, :mute_debug
12
+ attr_reader :default_format
13
+
14
+ Modes = %w{debug log info warn}.to_syms
15
+ NOPRINT = 4
16
+ NOLOG = 2
17
+ INLINE = 1
18
+
19
+ def initialize format={}
20
+ @clr = Coloring.new
21
+ @highlight = {
22
+ :warn => @clr.red_bold("WARN"),
23
+ :log => @clr.cyan("INFO"),
24
+ :info => @clr.cyan_bold("INFO"),
25
+ :debug => @clr.gray_bold("DEBUG")
26
+ }
27
+ @file_formats = Hash.new(@default_format = {})
28
+ set_format :global, format
29
+ end
30
+
31
+ def _set_format file, format
32
+ file.print = !format.q
33
+ file.out = format.out
34
+
35
+ file.path_format = '%'.in file.out if file.out
36
+ file.tf = format.time.to_a
37
+ file.cf0 = format.caller
38
+ file.cf = file.cf0.sub('%p'){'\1'}.sub('%f'){'\2'}.sub('%l'){'\3'}.sub('%m'){'\4'}
39
+ file.fmt = format.format
40
+ file._time, file._caller = '%time'.in(file.fmt), '%caller'.in(file.fmt)
41
+ end
42
+
43
+ def defaults
44
+ puts %{ :q => false, # not print
45
+ :out => false, # output to file, may have strftime's %H%M%Y for filename
46
+ :time => ["%H:%M:%S", "%03d"], # strftime, [msecs]
47
+ :caller => "#{@clr.gray('%f:%l')} #{@clr.red_bold(':%m')}", # file:line :method
48
+ :format => "%time %mode [%caller]: %text" # no comments}
49
+ end
50
+
51
+ # set any needed params, the rest will be set by default
52
+ def set_format *args
53
+ global, format = args.fetch_opts [nil],
54
+ :time => ["%H:%M:%S", "%03d"],
55
+ :caller => "#{@clr.gray('%f:%l')} #{@clr.red_bold(':%m')}",
56
+ :format => "%time %mode [%caller]: %text"
57
+ if global
58
+ _set_format @default_format, format
59
+ else
60
+ _set_format(file_format={}, format)
61
+ @file_formats[File.expand_path(caller[0].till ':')] = file_format
62
+ end
63
+ end
64
+
65
+ def get_format file=nil
66
+ cfg = @file_formats[file && File.expand_path(file)]
67
+ modes = Modes.reject {|m| send :"mute_#{m}"}
68
+ %{<Logger #{cfg.fmt.sub('%time', "%time(#{cfg.tf*'.'})").sub('%caller', "%caller(#{cfg.cf0})")}#{' -> '+cfg.out if cfg.out} #{modes.b ? modes.inspect : 'muted'}>}
69
+ end
70
+
71
+ def _print mode, text, opts, caler, bind, cfg
72
+ log_ = opts&NOLOG==0
73
+ print_ = opts&NOPRINT==0
74
+ str = cfg.fmt.dup
75
+ str.sub! "%mode", @highlight[mode]
76
+ if bind
77
+ text = bind.report text
78
+ elsif !text.is String
79
+ text = text.inspect
80
+ end
81
+ str.sub! "%text", text
82
+ str << "\n" if opts&INLINE==0
83
+ out = cfg.out
84
+ if cfg._time or cfg.path_format
85
+ now = Time.now
86
+ if cfg._time
87
+ time = now.strftime cfg.tf[0]
88
+ time << ".#{cfg.tf[1]%[now.usec/1000]}" if cfg.tf[1]
89
+ str.sub! "%time", time
90
+ end
91
+ out = now.strftime cfg.out if cfg.path_format
92
+ end
93
+ str.sub! "%caller", caler.sub(String::CALLER_RE, cfg.cf) if caler
94
+ log_str = @clr.clean str
95
+ RMTools.write out, log_str if log_
96
+ Kernel.print str if print_
97
+ end
98
+
99
+ def check_binding a
100
+ a[0].is(Binding) ? [a[0], a[1] || 0] : [nil, a[0] || 0]
101
+ end
102
+
103
+ def get_config!
104
+ @file_formats.empty? ? @default_format : @file_formats[File.expand_path(caller(2)[0].till ':')]
105
+ end
106
+
107
+ # controllers:
108
+ # - $panic: print debug messages
109
+ # - $verbose: print log messages
110
+ # - $quiet: print only warn messages regardless of other globals
111
+ # - @mute_warn, @mute_info, @mute_log: do not print
112
+ # this messages regardless of any globals
113
+ # - @out_all: write to file any messages
114
+
115
+ def warn text="\b\b ", *a
116
+ cfg = get_config!
117
+ if (cfg.out or cfg.print) && !@mute_warn
118
+ bind, opts = check_binding a
119
+ opts |= NOLOG if !cfg.out
120
+ opts |= NOPRINT if !cfg.print
121
+ text ||= yield if block_given?
122
+ _print(:warn, text, opts, cfg._caller && caller[0], bind, cfg)
123
+ end
124
+ end
125
+
126
+ def log text="\b\b ", *a
127
+ cfg = get_config!
128
+ if (cfg.out or cfg.print && !$quiet && $verbose) && !@mute_log
129
+ bind, opts = check_binding a
130
+ opts |= NOLOG if !cfg.out
131
+ opts |= NOPRINT if !(cfg.print && !$quiet && $verbose)
132
+ text ||= yield if block_given?
133
+ _print(:log, text, opts, cfg._caller && caller[0], bind, cfg)
134
+ end
135
+ end
136
+
137
+ def info text="\b\b ", *a
138
+ cfg = get_config!
139
+ if (cfg.print && !$quiet or cfg.out && cfg.out_all) && !@mute_info
140
+ bind, opts = check_binding a
141
+ opts |= NOLOG if !(cfg.out && cfg.out_all)
142
+ opts |= NOPRINT if !(cfg.print && !$quiet)
143
+ text ||= yield if block_given?
144
+ _print(:info, text, opts, cfg._caller && caller[0], bind, cfg)
145
+ end
146
+ end
147
+
148
+ def debug text="\b\b ", *a
149
+ cfg = get_config!
150
+ if (cfg.print && $panic && !$quiet or cfg.out && cfg.out_all) && !@mute_debug
151
+ bind, opts = check_binding a
152
+ opts |= NOLOG if !(cfg.out && cfg.out_all)
153
+ opts |= NOPRINT if !(cfg.print && $panic && !$quiet)
154
+ text ||= yield if block_given?
155
+ _print(:debug, text, opts, cfg._caller && caller[0], bind, cfg)
156
+ end
157
+ end
158
+
159
+ alias << info
160
+ alias < warn
161
+
162
+ Modes.each {|m| define_method("#{m}=") {|mute| send :"mute_#{m}=", !mute}}
163
+
164
+ def outall=(x) @default_format.out_all = x end
165
+ def print=(x) @default_format.print = x end
166
+ def out=(x) @default_format.out = x end
167
+
168
+ def out_all() @default_format.out_all end
169
+ def print() @default_format.print end
170
+ def out() @default_format.out end
171
+
172
+ def inspect() get_format end
173
+
174
+ end
175
+
176
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ class Object
3
+
4
+ def present
5
+ Hash[readable_variables.map {|v| [":#{v}", __send__(v)]}].present
6
+ end
7
+
8
+ end
9
+
10
+ class Array
11
+
12
+ def present(inspect_string=nil)
13
+ res = "[ "
14
+ indent = (size-1).to_s.size
15
+ res << map_with_index {|k,i|
16
+ "#{i.to_s.rjust(indent)}: #{(k.is String and !inspect_string) ? k : k.inspect}"
17
+ }*"\n "
18
+ res << "]"
19
+ puts res
20
+ end
21
+
22
+ end
23
+
24
+ class Hash
25
+
26
+ def present(inspect_string=nil)
27
+ str = "{ "
28
+ sorted = sort rescue to_a.sort_by_to_s
29
+ str << sorted.map {|k,v|
30
+ "#{(k.is String and !inspect_string) ? k : k.inspect} => #{(v.is String and !inspect_string) ? v : v.inspect},"
31
+ }*"\n "
32
+ str << "}"
33
+ puts str
34
+ end
35
+
36
+ end
37
+
38
+
@@ -0,0 +1,19 @@
1
+ require_with_path 'console/coloring'
2
+
3
+ module RMTools
4
+
5
+ def timer(ts=1, output=true)
6
+ timez = ts - 1
7
+ panic, verbose = $panic, $verbose
8
+ $panic = $verbose = false
9
+ t1 = Time.now
10
+ timez.times {yield}
11
+ res = yield
12
+ t2 = (Time.now.to_f*1000).round
13
+ t1 = (t1.to_f*1000).round
14
+ $panic, $verbose = panic, verbose
15
+ res = res.inspect
16
+ puts "#{output ? "res: #{res.size > 1000 ? res[0...1000]+"…" : res}\n" : "size of res string: #{res.to_s.size}, "}one: #{Painter.gray '%0.4fms'%[(t2-t1).to_f/ts]}, total: #{Painter.gray "#{(t2-t1).to_f}ms"}"
17
+ end
18
+
19
+ end
@@ -0,0 +1,92 @@
1
+ require_with_path 'debug/highlight'
2
+ module Kernel
3
+
4
+ # Python-like traceback for exceptions; uses ANSI coloring.
5
+ # In case of any low-level ruby error it may hang up interpreter
6
+ # (although you must have done creepy things for that). If you find
7
+ # interpreter in hanging up, require 'rmtools_notrace' instead of 'rmtools'
8
+ # or run "Exception.trace_format false" right after require
9
+ #
10
+ # 1:0> def divbyzero
11
+ # 2:1< 10/0 end
12
+ # => nil
13
+ # 3:0> divbyzero
14
+ # ZeroDivisionError: divided by 0
15
+ # from (irb):2:in `divbyzero' <- `/'
16
+ # >> 10/0 end
17
+ # from (irb):3
18
+ # >> divbyzero
19
+ def format_trace a
20
+ bt, calls, i = [], [], 0
21
+ # $log.info 'a.size', binding
22
+ m = a[0].parse:caller
23
+ while i < a.size
24
+ # $log.info i
25
+ m2 = a[i+1] && a[i+1].parse(:caller)
26
+ # $log.info 'm', binding
27
+ # $log.info 'm2', binding
28
+ # $log.info 'm[3] m[1..2]==m2[1..2]', binding if m and m2
29
+ # $log.info 'm[1] m[2]', binding if m
30
+ # $log.info highlighted_line(*m[1..2]) if m
31
+ if m and m.func and m2 and [m.path, m.line] == [m2.path, m2.line]
32
+ calls << "`#{m.func}' -> "
33
+ elsif m and m.line != 0 and line = highlighted_line(m.path, m.line)
34
+ bt << "#{a[i]}#{calls.join}\n#{line}"
35
+ calls = []
36
+ else bt << a[i]
37
+ end
38
+ i += 1
39
+ m = m2
40
+ end
41
+ # $log << Painter.r("FORMAT DONE! #{bt.size} lines formatted")
42
+ bt
43
+ end
44
+
45
+ end
46
+
47
+ class Class
48
+
49
+ def trace_format method
50
+ if Exception.in ancestors
51
+ class_eval(method ? %{
52
+ def set_backtrace src
53
+ src = #{method} src
54
+ set_bt src
55
+ end
56
+ } : %{
57
+ def set_backtrace src
58
+ set_bt src
59
+ end
60
+ })
61
+ else
62
+ raise NoMethodError, "undefined method `trace_format' for class #{self}"
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ # 1.9 may hung up processing IO while generating traceback
69
+ if RUBY_VERSION < '1.9'
70
+ class Exception
71
+ alias :set_bt :set_backtrace
72
+
73
+ # to use trace formatting ensure that you have SCRIPT_LINES__ constant set
74
+ # SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
75
+ #
76
+ # If you also set (e.g. in irbrc file)
77
+ # module Readline
78
+ # alias :orig_readline :readline
79
+ # def readline(*args)
80
+ # ln = orig_readline(*args)
81
+ # SCRIPT_LINES__['(irb)'] << "#{ln}\n"
82
+ # ln
83
+ # end
84
+ # end
85
+ # it will be possible to get the lines entered in IRB
86
+ # else it reads only ordinal require'd files
87
+
88
+ trace_format :format_trace
89
+ end
90
+
91
+ SystemStackError.trace_format false
92
+ end
@@ -0,0 +1 @@
1
+ require_with_path __FILE__, '*'
@@ -0,0 +1 @@
1
+ require_with_path 'debug', '{binding,logging,present,timer}'