rmtools 1.2.0 → 1.2.2b

Sign up to get free protection for your applications and to get access to all the features.
@@ -32,7 +32,8 @@ module RMTools
32
32
 
33
33
  def _set_format file, format
34
34
  file.print = !format.q
35
- file.out = format.out
35
+ file.out = format.out || format.log_file
36
+ file.color_out = format.color_out || format.color_log
36
37
 
37
38
  file.path_format = '%'.in file.out if file.out
38
39
  file.tf = format.time.to_a
@@ -95,7 +96,7 @@ module RMTools
95
96
  if caler
96
97
  str.sub! "%caller", caler.sub(String::CALLER_RE, cfg.cf)
97
98
  end
98
- log_str = @c.clean str
99
+ log_str = @c.clean str if !cfg.color_out
99
100
  RMTools.write out, log_str if log_
100
101
  Kernel.print str if print_
101
102
  end
@@ -156,9 +157,9 @@ module RMTools
156
157
  end
157
158
  end
158
159
 
159
- alias <= debug
160
- alias << info
161
- alias < warn
160
+ alias :<= :debug
161
+ alias :<< :info
162
+ alias :< :warn
162
163
 
163
164
  Modes.each {|m| define_method("#{m}=") {|mute| send :"mute_#{m}=", !mute}}
164
165
 
@@ -19,12 +19,19 @@ module RMTools
19
19
  # >> 10/0 end
20
20
  # from (irb):3
21
21
  # >> divbyzero
22
+
23
+ IgnoreFiles = %r{#{Regexp.escape $:.grep(%r{/ruby/1\.(8|9\.\d)$})[0]}/irb(/|\.rb$)|/active_support/dependencies.rb$}
24
+
22
25
  def format_trace(a)
23
26
  bt, calls, i = [], [], 0
24
27
  m = a[0].parse:caller
28
+ m.line -= 1 if m.file =~ /\.haml$/
25
29
  while i < a.size
26
30
  m2 = a[i+1] && a[i+1].parse(:caller)
27
- if m and m.func and m2 and [m.path, m.line] == [m2.path, m2.line]
31
+ m2.line -= 1 if m2 and m2.file =~ /\.haml$/
32
+ if m.path =~ IgnoreFiles
33
+ nil
34
+ elsif m and m.func and m2 and [m.path, m.line] == [m2.path, m2.line]
28
35
  calls << " -> `#{m.func}'"
29
36
  elsif m and m.line != 0 and line = RMTools.highlighted_line(m.path, m.line)
30
37
  bt << "#{a[i]}#{calls.join}\n#{line}"
@@ -2,7 +2,7 @@
2
2
  RMTools::require 'dev/trace_format'
3
3
  require 'active_support/core_ext/class/attribute'
4
4
 
5
- # 1.9 may hung up processing IO while generating traceback
5
+ # as for rmtools-1.1.0, 1.9 may hung up processing IO while generating traceback
6
6
  if RUBY_VERSION < '1.9'
7
7
  class Exception
8
8
  alias :set_bt :set_backtrace
@@ -20,6 +20,7 @@ if RUBY_VERSION < '1.9'
20
20
  # it will be possible to get the lines entered in IRB
21
21
  # else it reads only ordinal require'd files
22
22
  def set_backtrace src
23
+ message.hl! self.class
23
24
  if format = self.class.__trace_format
24
25
  src = RMTools.__send__ format, src
25
26
  end
@@ -89,6 +89,10 @@ class Array
89
89
  !find {|e| !yield(e)}
90
90
  end
91
91
 
92
+ def no?
93
+ !find {|e| yield(e)}
94
+ end
95
+
92
96
  # concatenation
93
97
  # analogue to String#>>
94
98
  def >>(ary)
@@ -14,12 +14,14 @@ unless defined? RMTools::Iterators
14
14
  # => [[1, 2, 3], [3, 4, 6]]
15
15
  class Array
16
16
  alias :throw_no :method_missing
17
- RMTools::Iterators = %r{(#{(%w{select reject partition find_all find sum foldr min max}+instance_methods.grep(/_by$/))*'|'})_([\w\d\_]+[!?]?)}
17
+ RMTools::Iterators = %r{^(#{(%w{every no select reject partition find_all find sum foldr}+instance_methods.grep(/_by$/))*'|'})_([\w\d\_]+[!?]?)}
18
18
 
19
19
  def method_missing(method, *args, &block)
20
20
  if match = (meth = method.to_s).match(RMTools::Iterators)
21
21
  iterator, meth = match[1], match[2].to_sym
22
22
  begin
23
+ iterator = :every? if iterator == :every
24
+ iterator = :no? if iterator == :no
23
25
  return iterator == :sum ?
24
26
  __send__(iterator, args.shift) {|i| i.__send__ meth, *args, &block}:
25
27
  __send__(iterator) {|i| i.__send__ meth, *args, &block}
@@ -27,9 +29,18 @@ unless defined? RMTools::Iterators
27
29
  e.message << " (`#{method}' interpreted as decorator-function `#{meth}')"
28
30
  raise e
29
31
  end
30
- elsif meth.sub!(/sses([!?]?)$/, 'ss\1') or meth.sub!(/ies([!?]?)$/, 'y\1') or meth.sub!(/s([!?]?)$/, '\1')
32
+ elsif meth.sub!(/sses([=!?]?)$/, 'ss\1') or meth.sub!(/ies([=!?]?)$/, 'y\1') or meth.sub!(/s([=!?]?)$/, '\1')
33
+ assignment = meth =~ /=$/
31
34
  meth = meth.to_sym
32
- begin return map {|i| i.__send__ meth, *args, &block}
35
+ begin
36
+ if assignment
37
+ if Array === args
38
+ each_with_index {|e,i| e.__send__ meth, args[i]}
39
+ else
40
+ each {|e| e.__send__ meth, args}
41
+ end
42
+ else map {|e| e.__send__ meth, *args, &block}
43
+ end
33
44
  rescue NoMethodError => e
34
45
  e.message << " (`#{method}' interpreted as map-function `#{meth}')"
35
46
  raise e
@@ -45,4 +45,8 @@ module Enumerable
45
45
  to_a + array.to_a
46
46
  end
47
47
 
48
+ def threadify(threads=4, &block)
49
+ RMTools::threadify(self, threads, &block)
50
+ end
51
+
48
52
  end
@@ -192,13 +192,21 @@ public
192
192
  end
193
193
 
194
194
  def empty?
195
- @range.empty?
195
+ @ranges.empty?
196
196
  end
197
197
 
198
198
  def include?(number_or_range)
199
199
  @ranges.find_include?(number_or_range)
200
200
  end
201
201
 
202
+ def begin
203
+ @ranges[0].begin
204
+ end
205
+
206
+ def end
207
+ @ranges[-1].end
208
+ end
209
+
202
210
  def size
203
211
  @ranges.sum_size
204
212
  end
@@ -87,4 +87,8 @@ class Dir
87
87
  }
88
88
  end
89
89
 
90
+ def self.threadify(threads=4, &block)
91
+ RMTools::threadify(Dir['*'], threads, &block)
92
+ end
93
+
90
94
  end
@@ -15,7 +15,9 @@ class File
15
15
  end
16
16
 
17
17
  def include?(str)
18
- while s = gets do return true if s.include? str end
18
+ while s = gets
19
+ return true if s.include? str
20
+ end
19
21
  end
20
22
 
21
23
  def parent
data/lib/rmtools/fs/io.rb CHANGED
@@ -43,13 +43,39 @@ module RMTools
43
43
  value.size
44
44
  end
45
45
 
46
- def read(df)
47
- df = df.tr '\\', '/'
48
- if File.file?(df)
49
- File.open(df, File::RDONLY) {|f| f.read}
50
- else
51
- warn "couldn't read from #{df.inspect}; file missed"
52
- end
46
+ # read('filename')
47
+ ### => 'text from filename'
48
+ # read('nonexistent_filename')
49
+ # couldn't read from "nonexistent_filename" (called from (irb):9001)
50
+ ### => nil
51
+ # read(['file1', 'file2', 'file3'])
52
+ ### => 'text from first of file1, file2, file3 that exists'
53
+ # read(['file1', 'file2'], ['nonexistent_file1', 'nonexistent_file2'])
54
+ # coludn't read from neither "nonexistent_file1", nor "nonexistent_file2" (called from (irb):9003)
55
+ ### => ['text from first of file1, file2 that exists', nil]
56
+ # read('file1', 'file2')
57
+ ### => ['text from file1', 'text from file2]
58
+ # read('file1', ['file2', 'file3'])
59
+ ### => ['text from file1', 'text from first of file2 and file3 that exists']
60
+ def read(*dests)
61
+ texts = dests.map {|dest|
62
+ dest = dest[0] if dest.size == 1
63
+ if dest.is Array
64
+ if file = dest.find {|f| File.file?(f.tr '\\', '/')}
65
+ File.open(file.tr('\\', '/'), File::RDONLY) {|f| f.read}
66
+ else
67
+ warn "couldn't read from neither #{dest[0].inspect} nor #{dest[1..-1].inspects*' nor '}; files missed (called from #{caller[0]})"
68
+ end
69
+ else
70
+ if File.file? dest.tr('\\', '/')
71
+ File.open(dest.tr('\\', '/'), File::RDONLY) {|f| f.read}
72
+ else
73
+ warn "couldn't read from #{dest.inspect}; file missed (called from #{caller[0]})"
74
+ end
75
+ end
76
+ }
77
+ texts = texts[0] if texts.size == 1
78
+ texts
53
79
  end
54
80
 
55
81
  module_function :read, :write, :rw
File without changes
@@ -17,6 +17,23 @@ class Array
17
17
  RMTools.randarr(len)
18
18
  end
19
19
 
20
+ def rand
21
+ if block_given?
22
+ h, ua = {}, uniq
23
+ s = ua.size
24
+ loop {
25
+ i = Kernel.rand size
26
+ if h[i]
27
+ return if h.size == s
28
+ elsif yield(e = ua[i])
29
+ return e
30
+ else h[i] = true
31
+ end
32
+ }
33
+ else self[Kernel.rand(size)]
34
+ end
35
+ end
36
+
20
37
  def rand!
21
38
  delete_at Kernel.rand size
22
39
  end
@@ -4,7 +4,7 @@ module Enumerable
4
4
  def rand
5
5
  if block_given?
6
6
  h, ua = {}, to_a.uniq
7
- size = ua.size
7
+ s = ua.size
8
8
  loop {
9
9
  i = Kernel.rand size
10
10
  if h[i]
@@ -20,7 +20,7 @@ module Enumerable
20
20
 
21
21
  def randsample(qty=Kernel.rand(size))
22
22
  a, b = [], to_a.dup
23
- qty.times {a << b.rand!}
23
+ [qty, size].min.times {a << b.rand!}
24
24
  a
25
25
  end
26
26
 
@@ -22,7 +22,7 @@ class StringScanner
22
22
  # node.sum {|n| n.__find(str, nslist).to_a} : node.__find(str, nslist)
23
23
  # }
24
24
  def each(re, cbs=nil, &cb)
25
- @last = 0
25
+ @last = pos
26
26
  res = scan_until re
27
27
  if cbs
28
28
  if cbs.is Hash
@@ -39,7 +39,7 @@ class StringScanner
39
39
  end
40
40
  else
41
41
  while res
42
- if cb = cbs.find {|pair| pair[0] and matched[pair[0]]}
42
+ if cb = cbs.find {|patern, fun| pattern and matched[pattern]}
43
43
  # patterns should be as explicit as possible
44
44
  cb[1][self, $~] if cb[1]
45
45
  @last = pos
@@ -61,10 +61,12 @@ class StringScanner
61
61
  end
62
62
 
63
63
  def head
64
- string[@last...pos-matched_size]
64
+ string[@last...pos-matched_size.to_i]
65
65
  end
66
66
 
67
- alias tail post_match
67
+ def tail
68
+ post_match || string[pos..-1]
69
+ end
68
70
 
69
71
  def hl_next(re)
70
72
  (res = scan_until re) && Painter.hl(string[[pos-1000, 0].max..pos+1000], res)
@@ -9,7 +9,7 @@ class String
9
9
  def sharp_split(splitter, *args)
10
10
  count, opts = args.fetch_opts [0, :flags], :include_splitter => true
11
11
  if !opts[:report_headers] and opts[:include_splitter] and splitter.is Regexp
12
- return split(/(?=#{splitter.source})/, count)
12
+ return split(/(?=#{splitter.source})/u, count)
13
13
  end
14
14
  a = split(splitter, count)
15
15
  return a if !opts[:include_splitter] and !opts[:report_headers]
@@ -67,7 +67,7 @@ class String
67
67
  add
68
68
  end
69
69
 
70
- def sanitize_blocks!(blocks, opts)
70
+ def sanitize_blocks!(blocks, maxlen, opts)
71
71
  blocks.reject! {|b| b.empty?} if opts[:no_blanks]
72
72
  blocks.strips! if opts[:strips]
73
73
  blocks.each {|b| raise Exception, "can't split string by #{terminator} to blocks with max length = #{maxlen}" if b.size > maxlen} if opts[:strict_overhead]
@@ -97,7 +97,7 @@ class String
97
97
  buf = buf_add + buf
98
98
  end
99
99
  if blocks.size == opts[:lines]
100
- return sanitize_blocks! blocks, opts
100
+ return sanitize_blocks! blocks, maxlen, opts
101
101
  end
102
102
  blocks << ''
103
103
  if buf
@@ -111,14 +111,14 @@ class String
111
111
  buf = nil
112
112
  end
113
113
  end
114
- sanitize_blocks! blocks, opts
114
+ sanitize_blocks! blocks, maxlen, opts
115
115
  end
116
116
 
117
117
  # 'An elegant way to factor duplication out of options passed to a series of method calls. Each method called in the block, with the block variable as the receiver, will have its options merged with the default options hash provided. '.cut_line 100
118
118
  # => "An elegant way to factor duplication out of options passed to a series of method calls..."
119
119
  def cut_line(maxlen, *opts)
120
120
  terminator, opts = opts.fetch_opts [:syntax, :flags]
121
- opts[:charsize] ||= RUBY_VERSION < '1.9' && a[0].cyr? ? 2 : 1
121
+ opts[:charsize] ||= RUBY_VERSION < '1.9' && cyr? ? 2 : 1
122
122
  return self if size <= maxlen
123
123
  maxlen -= 3
124
124
  split_to_blocks(maxlen*opts[:charsize], terminator, :strips => true, :strict_overhead => false, :lines => 1)[0][0, maxlen].chomp('.') + '...'
@@ -136,7 +136,7 @@ class String
136
136
  # options: charsize, no_blanks, strips
137
137
  def split_to_lines(maxlen, *opts)
138
138
  raise Exception, "Can't break text with maxlen = #{maxlen}" if maxlen < 1
139
- opts = opts.fetch_opts :flags, :strips=>true
139
+ opts = opts.fetch_opts [:flags], :strips=>true
140
140
  a = split("\n")
141
141
  opts[:charsize] ||= RUBY_VERSION < '1.9' && a[0].cyr? ? 2 : 1
142
142
  a.map {|string| string.strip.split_to_blocks(maxlen*opts[:charsize], opts.merge(:strict_overhead => false))}.flatten*"\n"
@@ -5,18 +5,27 @@ module LibXML::XML
5
5
  DefaultNS = {}
6
6
 
7
7
  FindByIndex = lambda {|node, ns, ss|
8
- node = node.is(Array) ?
9
- node.sum {|n| n.__find(nil, ns, ss)[ss.matched[1..-2].to_i].to_a} :
10
- node.__find(nil, ns, ss)[ss.matched[1..-2].to_i]
11
- node.is(Array) && node.size == 1 ? node[0] : node
8
+ index = ss.matched[1..-2]
9
+ if index.index('.')
10
+ range = Range(*index.split('..').to_is)
11
+ node = node.is(Array) ?
12
+ node.sum([]) {|n| n.__find(nil, ns, ss).to_a[range]} :
13
+ node.__find(nil, ns, ss).to_a[range]
14
+ else
15
+ node = node.is(Array) ?
16
+ node.map {|n| n.__find(nil, ns, ss)[index.to_i]}.compact :
17
+ node.__find(nil, ns, ss)[index.to_i]
18
+ end
19
+ node.is(Array) && node.size < 2 ? node[0] : node
12
20
  }
21
+
13
22
  FindByProc = lambda {|node, ns, ss|
14
23
  str_to_eval = ss.matched[1..-2]
15
- '_' >> str_to_eval if !str_to_eval['_']
24
+ block = eval "lambda {|_| #{'_' if !str_to_eval['_']}#{str_to_eval}}"
16
25
  node = node.is(Array) ?
17
- node.sum {|n| n.__find(nil, ns, ss).select{|_| eval str_to_eval}.to_a} :
18
- node.__find(nil, ns, ss).select{|_| eval str_to_eval}
19
- node.is(Array) && node.size == 1 ? node[0] : node
26
+ node.sum([]) {|n| n.__find(nil, ns, ss).select(&block).to_a} :
27
+ node.__find(nil, ns, ss).select(&block)
28
+ node.is(Array) && node.size < 2 ? node[0] : node
20
29
  }
21
30
 
22
31
  class Node
@@ -31,7 +40,7 @@ module LibXML::XML
31
40
  def find(xpath, nslist=DefaultNS)
32
41
  node = self
33
42
  ss = StringScanner.new xpath
34
- ss.each %r{\[-?\d+\]|\{[^\}]+\}},
43
+ ss.each %r{\[-?\d+(\.\.\d+)?\]|\{[^\}]+\}},
35
44
  ?[ => lambda {|ss|
36
45
  if node; node = FindByIndex[node, nslist, ss]
37
46
  else return [] end },
@@ -40,7 +49,7 @@ module LibXML::XML
40
49
  else return [] end },
41
50
  nil => lambda {|str|
42
51
  node = node.is(Array) ?
43
- node.sum {|n| n.__find(str, nslist).to_a} : node.__find(str, nslist)
52
+ node.sum([]) {|n| n.__find(str, nslist).to_a} : node.__find(str, nslist)
44
53
  }
45
54
  node ? (!ss.eos? || node.is(Array)) ? node : [node] : []
46
55
  end
@@ -64,7 +73,7 @@ module LibXML::XML
64
73
  xpath.sub!(/^([\w*])/, '//\1')
65
74
  node = self
66
75
  ss = StringScanner.new xpath
67
- ss.each %r{\[-?\d+\]|\{[^\}]+\}},
76
+ ss.each %r{\[-?\d+(\.\.\d+)?\]|\{[^\}]+\}},
68
77
  ?[ => lambda {|ss|
69
78
  if node; node = FindByIndex[node, nslist, ss]
70
79
  else return [] end },
@@ -73,7 +82,7 @@ module LibXML::XML
73
82
  else return [] end },
74
83
  nil => lambda {|str|
75
84
  node = node.is(Array) ?
76
- node.sum {|n| n.__find(str, nslist).to_a} : node.__find(str, nslist)
85
+ node.sum([]) {|n| n.__find(str, nslist).to_a} : node.__find(str, nslist)
77
86
  }
78
87
  node ? (!ss.eos? || node.is(Array)) ? node : [node] : []
79
88
  end
@@ -25,10 +25,15 @@ class String
25
25
  str = b || "<html/>"
26
26
  doc = if forceutf
27
27
  XML::HTMLParser.string(str.xml_to_utf, :options => 97,
28
- :encoding => XML::Encoding::UTF_8).parse
28
+ :encoding => XML::Encoding::UTF_8).parse
29
29
  else
30
30
  begin
31
- XML::HTMLParser.string(str, :options => 97).parse
31
+ if RUBY_VERSION > '1.9'
32
+ XML::HTMLParser.string(str, :options => 97,
33
+ :encoding => XML::Encoding.const_get(__ENCODING__.to_s.tr('-','_').to_sym)).parse
34
+ else
35
+ XML::HTMLParser.string(str, :options => 97).parse
36
+ end
32
37
  rescue
33
38
  if enc = xml_charset
34
39
  XML::HTMLParser.string(str, :options => 97,
data/lib/rmtools_dev.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
2
2
  $__MAIN__ = self
3
- require 'rmtools/load'
3
+ require 'rmtools/init'
4
4
  RMTools::require 'dev'
5
5
 
6
6
  unless defined? Rails; class Object; include RMTools end end