rmtools 1.1.10 → 1.1.11

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.
data/Manifest.txt CHANGED
@@ -93,8 +93,8 @@ lib/rmtools/conversions/enum.rb
93
93
  lib/rmtools/conversions/int.rb
94
94
  lib/rmtools/enumerable.rb
95
95
  lib/rmtools_notrace.rb
96
+ lib/rmtools_safe.rb
96
97
  lib/rmtools_nodebug.rb
97
- lib/rmtools_no_b.rb
98
98
  ./Rakefile
99
99
  ./Manifest.txt
100
100
  ./License.txt
data/README.txt CHANGED
@@ -8,6 +8,12 @@ Methods for basic classes addon collection.
8
8
 
9
9
  == CHANGES
10
10
 
11
+ === Version 1.1.11
12
+
13
+ * Fixed Hash#unify_keys for 1.9.2
14
+ * Speeded Array#uniq_by up
15
+ * Added some shortcut methods for ActiveRecord::Base
16
+
11
17
  === Version 1.1.10
12
18
 
13
19
  * Some bugfixes for previous updates
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rake'
2
2
  require 'lib/rmtools/install'
3
3
  compile_manifest
4
4
 
5
- RMTOOLS_VERSION = '1.1.10'
5
+ RMTOOLS_VERSION = '1.1.11'
6
6
  begin
7
7
  require 'hoe'
8
8
  config = Hoe.spec 'rmtools' do
data/ext/rmtools.cpp CHANGED
@@ -193,21 +193,28 @@ static VALUE rb_str_conjunction(VALUE self, VALUE str)
193
193
  * => [8, 5]
194
194
  * a
195
195
  * => [8, 5]
196
+ * Here is implyied that callback block is +clean function+
196
197
  */
197
198
  static VALUE rb_ary_uniq_by_bang(VALUE ary)
198
199
  {
199
200
  if (!rb_block_given_p())
200
201
  return rb_ary_new4(RARRAY_LEN(ary), RARRAY_PTR(ary));
201
- VALUE hash, res;
202
+ VALUE hash, res_hash, res, el;
202
203
  long i, j;
203
204
 
204
205
  hash = rb_hash_new();
206
+ res_hash = rb_hash_new();
205
207
  for (i=j=0; i<RARRAY_LEN(ary); i++) {
206
- res = rb_yield(RARRAY_PTR(ary)[i]);
207
- if (!st_lookup(RHASH_TBL(hash), res, 0)) {
208
- rb_ary_store(ary, j++, RARRAY_PTR(ary)[i]);
209
- rb_hash_aset(hash, res, RARRAY_PTR(ary)[i]);
210
- }
208
+ // We store an element itself and so we won't calculate function of it
209
+ // other time we'll find it in source. Ruby store function is very fast,
210
+ // so we can neglect its runtime even if source array is allready uniq
211
+ el = RARRAY_PTR(ary)[i];
212
+ if (st_lookup(RHASH_TBL(hash), el, 0)) continue;
213
+ res = rb_yield(el);
214
+ if (st_lookup(RHASH_TBL(res_hash), res, 0)) continue;
215
+ rb_hash_aset(hash, el, Qtrue);
216
+ rb_hash_aset(res_hash, res, Qtrue);
217
+ rb_ary_store(ary, j++, el);
211
218
  }
212
219
  ARY_SET_LEN(ary, j);
213
220
 
@@ -400,12 +407,14 @@ static VALUE rb_hash_map_pairs(VALUE hash)
400
407
  */
401
408
  static VALUE rb_math_factorial(VALUE x)
402
409
  {
403
- if (FIX2LONG(x) < 2) return x;
404
- return rb_big_mul(x, rb_math_factorial(LONG2FIX(FIX2LONG(x) - 1)));
410
+ long a = FIX2LONG(x);
411
+ for (int i = 2; i < a; i++)
412
+ x = TYPE(x) == T_BIGNUM ?
413
+ rb_big_mul(x, rb_int2big(i)) :
414
+ rb_big_mul(rb_int2big(FIX2LONG(x)), rb_int2big(i));
415
+ return x;
405
416
  }
406
417
 
407
-
408
-
409
418
  static int unsigned_big_lte(VALUE x, VALUE y)
410
419
  {
411
420
  long xlen = RBIGNUM_LEN(x);
@@ -26,6 +26,7 @@ module ActiveRecord
26
26
  end
27
27
 
28
28
  def to_hash
29
+ return attributes if respond_to? :attributes
29
30
  serializer = Serializer.new(self)
30
31
  serializer.respond_to?(:attributes_hash) ?
31
32
  serializer.attributes_hash :
@@ -33,9 +34,22 @@ module ActiveRecord
33
34
  end
34
35
 
35
36
  alias :delete_with_id :delete
36
- # a problem was: model.delete() won't work if it has no id. Just delete() it if has
37
- def delete
38
- id ? delete_with_id : self.class.delete_all(attributes)
37
+ alias :destroy_with_id :destroy
38
+ # by default model.delete() and model.destroy() won't work if model has no id
39
+ def delete(field=nil)
40
+ id ?
41
+ delete_with_id :
42
+ field ?
43
+ self.class.delete_all(field => __send__(field)) :
44
+ self.class.delete_all(attributes)
45
+ end
46
+
47
+ def destroy(field=nil)
48
+ id ?
49
+ destroy_with_id :
50
+ field ?
51
+ self.class.destroy_all(field => __send__(field)) :
52
+ self.class.destroy_all(attributes)
39
53
  end
40
54
 
41
55
  def self.merge_conditions(*conditions)
@@ -47,6 +61,21 @@ module ActiveRecord
47
61
  "(#{segments.join(') AND (')})" unless segments.empty?
48
62
  end
49
63
 
64
+ def self.execute_sanitized(sql)
65
+ connection.execute sanitize_sql sql
66
+ end
67
+
68
+ # requires primary key
69
+ def self.forced_create(hash)
70
+ names = columns.names
71
+ id = (hash[primary_key.to_sym] ||= maximum(primary_key)+1)
72
+ execute_sanitized([
73
+ "INSERT INTO #{quoted_table_name} VALUES (:#{names*', :'})",
74
+ Hash[names.map {|name| [name.to_sym, nil]}].merge(hash)
75
+ ])
76
+ find_by_sql(["SELECT * FROM #{quoted_table_name} WHERE #{primary_key} = ?", id])[0]
77
+ end
78
+
50
79
  end
51
80
 
52
81
  end
@@ -17,4 +17,5 @@ module RMTools
17
17
  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"}"
18
18
  end
19
19
 
20
+ module_function :timer
20
21
  end
@@ -18,7 +18,7 @@ class Array
18
18
  case top
19
19
  when Numeric; ratio = max.to_f/top
20
20
  when Array; ratio = zip(top).map {|a,b| b ? a.to_f/b : 0}.max
21
- else raise TypeError, "number or array of numbers expceted, #{top.class} given"
21
+ else raise TypeError, "number or array of numbers expected, #{top.class} given"
22
22
  end
23
23
  map {|e| e/ratio}
24
24
  end
@@ -20,14 +20,20 @@ unless defined? RMTools::Iterators
20
20
  if match = (meth = method.to_s).match(RMTools::Iterators)
21
21
  iterator, meth = match[1..2]
22
22
  meth = meth.to_sym
23
- return send(iterator) {|i| i.__send__ meth, *args, &block}
23
+ begin return send(iterator) {|i| i.__send__ meth, *args, &block}
24
+ rescue NoMethodError => e
25
+ e.message << " (`#{method}' interpreted as decorator-function `#{meth}')"
26
+ raise e
27
+ end
24
28
  elsif meth.sub!(/sses([!?]?)$/, 'ss\1') or meth.sub!(/ies([!?]?)$/, 'y\1') or meth.sub!(/s([!?]?)$/, '\1')
25
- return map {|i| i.__send__ meth.to_sym, *args, &block}
26
- else
27
- throw_no method
28
- end
29
- rescue NoMethodError
30
- throw_no method
29
+ meth = meth.to_sym
30
+ begin return map {|i| i.__send__ meth, *args, &block}
31
+ rescue NoMethodError => e
32
+ e.message << " (`#{method}' interpreted as map-function `#{meth}')"
33
+ raise e
34
+ end
35
+ else throw_no method
36
+ end
31
37
  end
32
38
  end
33
39
 
@@ -8,6 +8,20 @@ class Hash
8
8
  merge(other_hash || {})
9
9
  end
10
10
 
11
+ if RUBY_VERSION >= '1.9.2'
12
+ def unify_keys
13
+ keys.each {|k|
14
+ if k.is String
15
+ sk = k.to_sym
16
+ self[sk] = self[k] if !self[sk]
17
+ elsif k.is Symbol
18
+ sk = k.to_s
19
+ self[sk] = self[k] if !self[sk]
20
+ end
21
+ }
22
+ self
23
+ end
24
+ else
11
25
  def unify_keys
12
26
  each {|k, v|
13
27
  if k.is String
@@ -19,6 +33,7 @@ class Hash
19
33
  end
20
34
  }
21
35
  end
36
+ end
22
37
 
23
38
  def max_by_key; [(m = keys.max), self[m]] end
24
39
 
@@ -42,11 +42,11 @@ class Range
42
42
  (self.begin <=> range.begin).b || self.include_end.end <=> range.include_end.end
43
43
  end
44
44
 
45
- def include_end()
45
+ def include_end
46
46
  exclude_end? ? self.begin..(self.end - 1) : self
47
47
  end
48
48
 
49
- def center()
49
+ def center
50
50
  (first + last + (!exclude_end?).to_i)/2
51
51
  end
52
52
 
@@ -54,7 +54,7 @@ class Range
54
54
  first + (i-1)*size/j .. first - 1 + i*size/j unless i < 1 or j < 1 or j < i
55
55
  end
56
56
 
57
- def size()
57
+ def size
58
58
  last - first + (!exclude_end?).to_i
59
59
  end
60
60
 
@@ -92,6 +92,13 @@ class Range
92
92
  select {|i| i%2 == 0}
93
93
  end
94
94
 
95
+ def sum
96
+ ie = include_end.end
97
+ return (1..ie).sum - (0..-self.begin).sum if self.begin < 0
98
+ return 0 if ie < self.begin
99
+ ie*(ie+1)/2 - (1..self.begin-1).sum
100
+ end
101
+
95
102
  end
96
103
 
97
104
  class XRange
data/lib/rmtools/fs/io.rb CHANGED
@@ -48,9 +48,9 @@ module RMTools
48
48
  if File.file?(df)
49
49
  File.open(df, File::RDONLY) {|f| f.read}
50
50
  else
51
- STDERR.puts "couldn't read from #{df.inspect}; file missed"
51
+ warn "couldn't read from #{df.inspect}; file missed"
52
52
  end
53
53
  end
54
54
 
55
- module_function :rw, :write, :read
55
+ module_function :read, :write, :rw
56
56
  end
@@ -45,6 +45,6 @@ module RMTools
45
45
  STDERR.puts "#{df} is missed!"
46
46
  end
47
47
  end
48
-
48
+
49
49
  module_function :tail, :tail_n, :read_lines
50
50
  end
data/lib/rmtools/load.rb CHANGED
@@ -11,9 +11,3 @@ module RMTools
11
11
  '../rmtools.so'
12
12
  ].each {|file| RMTools::require file}
13
13
  end
14
-
15
- # Comment out in case of any method conflicts
16
- # Library methods use module functions explicitly
17
- class Object; include RMTools end
18
-
19
- # default logger now initialized in debug/logging
@@ -3,12 +3,29 @@ require 'strscan'
3
3
 
4
4
  class StringScanner
5
5
  attr_reader :last
6
+ __init__
6
7
 
8
+ # #each( <Regexp>, { <0..255> => ->{|self|}, ... } )
9
+ # #each( <Regexp>, [ [ <Regexp>, ->{|self, <MatchData>|} ], ... ] )
10
+ # #each( <Regexp> ) {|self|}
11
+ # Example:
12
+ # ss = StringScanner.new xpath
13
+ # ss.each %r{\[-?\d+\]|\{[^\}]+\}},
14
+ # ?[ => lambda {|ss|
15
+ # if node; node = FindByIndex[node, nslist, ss]
16
+ # else return [] end },
17
+ # ?{ => lambda {|ss|
18
+ # if node; node = FindByProc[node, nslist, ss]
19
+ # else return [] end },
20
+ # nil => lambda {|str|
21
+ # node = node.is(Array) ?
22
+ # node.sum {|n| n.__find(str, nslist).to_a} : node.__find(str, nslist)
23
+ # }
7
24
  def each(re, cbs=nil, &cb)
8
25
  @last = 0
9
26
  res = scan_until re
10
27
  if cbs
11
- if cbs.keys.compact[0].is Fixnum
28
+ if cbs.is Hash
12
29
  while res
13
30
  if cb = cbs[matched.ord]
14
31
  cb[self]
@@ -17,27 +34,30 @@ class StringScanner
17
34
  else break
18
35
  end
19
36
  end
37
+ if !eos? and cb = cbs[nil]
38
+ cb[tail]
39
+ end
20
40
  else
21
41
  while res
22
- if cb = cbs.find {|pattern, proc| pattern and pattern.in matched}
23
- # patterns must be as explicit as possible
24
- cb[1][self]
42
+ if cb = cbs.find {|pair| pair[0] and matched[pair[0]]}
43
+ # patterns should be as explicit as possible
44
+ cb[1][self, $~]
25
45
  @last = pos
26
46
  res = !eos? && scan_until(re)
27
47
  else break
28
48
  end
29
49
  end
50
+ if !eos? and cb = cbs.find {|pair| pair[0].nil?}
51
+ cb[1][tail]
52
+ end
30
53
  end
31
54
  else
32
55
  while res
33
- cb[self]
34
- @last = pos
35
- res = !eos? && scan_until(re)
56
+ cb[self]
57
+ @last = pos
58
+ res = !eos? && scan_until(re)
36
59
  end
37
60
  end
38
- if (cb = cbs[nil]) and !eos?
39
- cb[tail]
40
- end
41
61
  end
42
62
 
43
63
  def head
data/lib/rmtools.rb CHANGED
@@ -4,4 +4,6 @@ $__MAIN__ = self
4
4
  require 'rmtools/load'
5
5
  RMTools::require 'b'
6
6
  RMTools::require 'debug'
7
- RMTools::require 'console'
7
+ RMTools::require 'console'
8
+
9
+ unless defined? Rails; class Object; include RMTools end end
File without changes
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rmtools
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
- - 10
10
- version: 1.1.10
9
+ - 11
10
+ version: 1.1.11
11
11
  platform: ruby
12
12
  authors:
13
13
  - Shinku
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-24 00:00:00 +03:00
18
+ date: 2011-04-03 00:00:00 +04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -173,8 +173,8 @@ files:
173
173
  - lib/rmtools/conversions/int.rb
174
174
  - lib/rmtools/enumerable.rb
175
175
  - lib/rmtools_notrace.rb
176
+ - lib/rmtools_safe.rb
176
177
  - lib/rmtools_nodebug.rb
177
- - lib/rmtools_no_b.rb
178
178
  - ./Rakefile
179
179
  - ./Manifest.txt
180
180
  - ./License.txt