rmtools 1.2.0 → 1.2.2b

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