rmtools 1.1.10 → 1.1.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
|