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 +1 -1
- data/README.txt +6 -0
- data/Rakefile +1 -1
- data/ext/rmtools.cpp +19 -10
- data/lib/rmtools/db/active_record.rb +32 -3
- data/lib/rmtools/debug/timer.rb +1 -0
- data/lib/rmtools/enumerable/array.rb +1 -1
- data/lib/rmtools/enumerable/array_iterators.rb +13 -7
- data/lib/rmtools/enumerable/hash.rb +15 -0
- data/lib/rmtools/enumerable/range.rb +10 -3
- data/lib/rmtools/fs/io.rb +2 -2
- data/lib/rmtools/fs/tools.rb +1 -1
- data/lib/rmtools/load.rb +0 -6
- data/lib/rmtools/text/string_scanner.rb +30 -10
- data/lib/rmtools.rb +3 -1
- data/lib/{rmtools_no_b.rb → rmtools_safe.rb} +0 -0
- metadata +5 -5
data/Manifest.txt
CHANGED
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
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
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
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
|
-
|
404
|
-
|
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
|
-
|
37
|
-
|
38
|
-
|
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
|
data/lib/rmtools/debug/timer.rb
CHANGED
@@ -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
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
51
|
+
warn "couldn't read from #{df.inspect}; file missed"
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
module_function :
|
55
|
+
module_function :read, :write, :rw
|
56
56
|
end
|
data/lib/rmtools/fs/tools.rb
CHANGED
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.
|
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 {|
|
23
|
-
# patterns
|
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
|
-
|
34
|
-
|
35
|
-
|
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
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:
|
4
|
+
hash: 5
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 1.1.
|
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
|
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
|