rmtools 2.0.0 → 2.1.0

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/README.md CHANGED
@@ -27,6 +27,18 @@ It's still randomly documented since it's just my working tool.
27
27
 
28
28
  ### CHANGES
29
29
 
30
+ ##### Version 2.1.0
31
+
32
+ * Array
33
+ * For ruby >= 1.9.3 #uniq_by[!] is alias of #uniq[!] itself, since it’s native implementation appears to be ~1.4x faster
34
+ * A bit better english singularizer for iterators
35
+ * Added #partition_by iterator
36
+ * Enumerable
37
+ * Generalized faster set operations for Array and Set (see rmtools/enumerable/set_ops)
38
+ * Boosted &-operator
39
+ * ActiveRecord::Base
40
+ * Added #update_attributes?
41
+
30
42
  ##### Version 2.0.0
31
43
 
32
44
  * Array Meta-iterators
data/ext/rmtools.cpp CHANGED
@@ -199,6 +199,9 @@ static VALUE rb_str_conjunction(VALUE self, VALUE str)
199
199
  */
200
200
  static VALUE rb_ary_uniq_by_bang(VALUE ary)
201
201
  {
202
+ long len = RARRAY_LEN(ary);
203
+ if (len < 2)
204
+ return Qnil;
202
205
  if (!rb_block_given_p())
203
206
  return rb_ary_new4(RARRAY_LEN(ary), RARRAY_PTR(ary));
204
207
  VALUE hash, res_hash, res, el;
@@ -206,7 +209,7 @@ static VALUE rb_ary_uniq_by_bang(VALUE ary)
206
209
 
207
210
  hash = rb_hash_new();
208
211
  res_hash = rb_hash_new();
209
- for (i=j=0; i<RARRAY_LEN(ary); i++) {
212
+ for (i=j=0; i<len; i++) {
210
213
  // We store an element itself and so we won't calculate function of it
211
214
  // other time we'll find it in source. Ruby store function is very fast,
212
215
  // so we can neglect its runtime even if source array is allready uniq
@@ -220,7 +223,7 @@ static VALUE rb_ary_uniq_by_bang(VALUE ary)
220
223
  }
221
224
  ARY_SET_LEN(ary, j);
222
225
 
223
- return ary;
226
+ return j == len ? Qnil : ary;
224
227
  }
225
228
 
226
229
  /*
@@ -228,7 +231,9 @@ static VALUE rb_ary_uniq_by_bang(VALUE ary)
228
231
  */
229
232
  static VALUE rb_ary_uniq_by(VALUE ary)
230
233
  {
231
- return rb_ary_uniq_by_bang(rb_ary_dup(ary));
234
+ VALUE ary_dup = rb_ary_dup(ary);
235
+ rb_ary_uniq_by_bang(ary_dup);
236
+ return ary_dup;
232
237
  }
233
238
 
234
239
  /*
@@ -152,7 +152,7 @@ module ActiveRecord
152
152
  id ?
153
153
  delete_with_id :
154
154
  field ?
155
- self.class.delete_all(field => __send__(field)) :
155
+ self.class.delete_all(field => self[field]) :
156
156
  self.class.delete_all(attributes)
157
157
  end
158
158
 
@@ -160,7 +160,7 @@ module ActiveRecord
160
160
  id ?
161
161
  destroy_with_id :
162
162
  field ?
163
- self.class.destroy_all(field => __send__(field)) :
163
+ self.class.destroy_all(field => self[field]) :
164
164
  self.class.destroy_all(attributes)
165
165
  end
166
166
 
@@ -171,6 +171,11 @@ module ActiveRecord
171
171
  def with_same(attr)
172
172
  self.class.where(attr => self[attr])
173
173
  end
174
+
175
+ def update_attributes?(hash)
176
+ hash.each {|k, v| self[k] = v}
177
+ changed? && save
178
+ end
174
179
 
175
180
  end
176
181
 
@@ -1,71 +1,10 @@
1
1
  # encoding: utf-8
2
2
  require 'active_support/core_ext/array'
3
3
  RMTools::require 'functional/fold'
4
+ RMTools::require 'enumerable/set_ops'
4
5
 
5
6
  class Array
6
- # builtin methods overwrite
7
- # why should we do zillions of cycles just for ensure A | [] = A - [] = A or A & [] = []
8
- # though - and & should be improved within C-extension to break loop when no items have lost in self
9
- alias union |
10
- alias coallition +
11
- alias subtraction -
12
- alias intersection &
13
- private :union, :coallition, :subtraction, :intersection
14
-
15
- def |(ary)
16
- if empty?
17
- ary.uniq
18
- elsif ary.respond_to? :empty? and ary.empty?
19
- dup
20
- else union(ary)
21
- end
22
- end
23
-
24
- def +(ary)
25
- if empty?
26
- if ary.respond_to? :empty? and ary.empty?
27
- []
28
- else ary.dup
29
- end
30
- elsif ary.respond_to? :empty? and ary.empty?
31
- dup
32
- else coallition(ary)
33
- end
34
- end
35
-
36
- def -(ary)
37
- if empty?
38
- []
39
- elsif ary.respond_to? :empty? and ary.empty?
40
- dup
41
- else subtraction(ary)
42
- end
43
- end
44
-
45
- def &(ary)
46
- if empty? or (ary.respond_to? :empty? and ary.empty?)
47
- []
48
- else intersection(ary)
49
- end
50
- end
51
-
52
- def ^(ary)
53
- if empty? or (ary.respond_to? :empty? and ary.empty?)
54
- [dup, ary.dup]
55
- elsif self == ary
56
- [[], []]
57
- else
58
- common = intersection ary
59
- [self - common, ary - common]
60
- end
61
- end
62
-
63
- alias diff ^
64
-
65
- def intersects?(ary)
66
- (self & ary).any?
67
- end
68
- alias :x? :intersects?
7
+ include RMTools::SmarterSetOps
69
8
 
70
9
  # arithmetics
71
10
  def avg
@@ -184,6 +123,14 @@ class Array
184
123
  reject {|e| e.__send__(key) == value}
185
124
  end
186
125
 
126
+ def partition_by(key, value)
127
+ partition {|e| e.__send__(key) == value}
128
+ end
129
+
130
+ if RUBY_VERSION >= '1.9.3'
131
+ alias :uniq_by :uniq
132
+ alias :uniq_by! :uniq!
133
+ end
187
134
 
188
135
  # uniqs
189
136
  def uniq?
@@ -15,6 +15,14 @@ class Array
15
15
  mattr_reader :iterators_names, :iterators_pattern
16
16
  @@iterators_names = []
17
17
 
18
+ private
19
+ def simple_inplace_singularize!(noun)
20
+ noun.sub!(/(ss|[sc]h|[xo])es([=!?]?)$/, '\1\2') or
21
+ noun.sub!(/ies([=!?]?)$/, 'y\1') or
22
+ noun.sub!(/ves([=!?]?)$/, 'f\1') or
23
+ noun.sub!(/s([=!?]?)$/, '\1')
24
+ end
25
+
18
26
  class << self
19
27
 
20
28
  def add_iterator_name(name_or_list)
@@ -65,7 +73,7 @@ class Array
65
73
 
66
74
  return case iterator
67
75
  when :sum, :sort_along_by; __send__(iterator, args.shift) {|i| i.__send__ meth, *args, &block}
68
- when :find_by, :select_by, :reject_by; __send__(iterator, meth, *args)
76
+ when :find_by, :select_by, :reject_by, :partition_by; __send__(iterator, meth, *args)
69
77
  else __send__(iterator) {|i| i.__send__ meth, *args, &block}
70
78
  end
71
79
  rescue NoMethodError => e
@@ -73,7 +81,7 @@ class Array
73
81
  raise e
74
82
  end
75
83
 
76
- elsif meth.sub!(/sses([=!?]?)$/, 'ss\1') or meth.sub!(/ies([=!?]?)$/, 'y\1') or meth.sub!(/s([=!?]?)$/, '\1')
84
+ elsif simple_inplace_singularize!(meth)
77
85
  assignment = meth =~ /=$/
78
86
  meth = meth.to_sym
79
87
 
@@ -100,7 +108,7 @@ class Array
100
108
 
101
109
  end # << self
102
110
 
103
- add_iterator_name(instance_methods.grep(/_by$/)+%w{every no select reject partition find_all find sum foldr foldl fold count rand_by})
111
+ add_iterator_name(instance_methods.grep(/_by$/)+%w{every no which select reject partition find_all find sum foldr foldl fold count rand_by})
104
112
 
105
113
  # Benchmark 2:
106
114
  #
@@ -161,7 +169,7 @@ class Array
161
169
  end
162
170
  end
163
171
 
164
- elsif meth.sub!(/sses([=!?]?)$/, 'ss\1') or meth.sub!(/ies([=!?]?)$/, 'y\1') or meth.sub!(/s([=!?]?)$/, '\1')
172
+ elsif simple_inplace_singularize!(meth)
165
173
  assignment = meth =~ /=$/
166
174
  meth = meth.to_sym
167
175
 
@@ -236,7 +244,7 @@ class Array
236
244
  err.message << " (`#{method}' interpreted as decorator-function `#{meth}')"
237
245
  raise err
238
246
  end}
239
- when :find_by, :rfind_by,:select_by, :reject_by
247
+ when :find_by, :rfind_by, :select_by, :reject_by, :partition_by
240
248
  Array.class_eval %{
241
249
  def #{method}(val)
242
250
  # select_by_count(max_count) =>
@@ -258,7 +266,7 @@ class Array
258
266
  end}
259
267
  end
260
268
 
261
- elsif meth.sub!(/sses([=!?]?)$/, 'ss\1') or meth.sub!(/ies([=!?]?)$/, 'y\1') or meth.sub!(/s([=!?]?)$/, '\1')
269
+ elsif simple_inplace_singularize!(meth)
262
270
  assignment = meth =~ /=$/
263
271
  meth = meth.to_sym
264
272
 
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ require 'set'
3
+ RMTools::require 'enumerable/set_ops'
4
+
5
+ class Set
6
+ alias :uniq :dup
7
+ include RMTools::SmarterSetOps
8
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+ module RMTools
3
+
4
+ # Builtin methods overwrite.
5
+ # Why should we do zillions of cycles just for ensure
6
+ # `A | [] = A - [] = A or A & [] = []`
7
+ # ?
8
+ # Though #- and #& should be improved within C-extension to break loop when no items have had lost in self (Or not? Don't remember what I had on my mind while I've being writing this)
9
+ module SmarterSetOps
10
+
11
+ def self.included(acceptor)
12
+ acceptor.class_eval {
13
+ alias :union :|
14
+ alias :coallition :+
15
+ alias :subtraction :-
16
+ alias :intersection :&
17
+ protected :union, :coallition, :subtraction, :intersection
18
+
19
+ def |(ary)
20
+ return ary.uniq if empty?
21
+ return uniq if ary.respond_to? :empty? and ary.empty?
22
+
23
+ union ary
24
+ end
25
+
26
+ def +(ary)
27
+ if empty?
28
+ return [] if ary.respond_to? :empty? and ary.empty?
29
+ ary.dup
30
+ end
31
+ return dup if ary.respond_to? :empty? and ary.empty?
32
+
33
+ coallition ary
34
+ end
35
+
36
+ def -(ary)
37
+ return [] if empty?
38
+ return dup if ary.respond_to? :empty? and ary.empty?
39
+
40
+ subtraction ary
41
+ end
42
+
43
+ def &(ary)
44
+ return [] if empty? or (ary.respond_to? :empty? and ary.empty?)
45
+ return ary.intersection self if size < ary.size
46
+
47
+ intersection ary
48
+ end
49
+
50
+ def ^(ary)
51
+ return [dup, ary.dup] if empty? or (ary.respond_to? :empty? and ary.empty?)
52
+ return [[], []] if self == ary
53
+
54
+ common = intersection ary
55
+ [self - common, ary - common]
56
+ end
57
+
58
+ alias diff ^
59
+
60
+ def intersects?(ary)
61
+ (self & ary).any?
62
+ end
63
+ alias :x? :intersects?
64
+ }
65
+ super
66
+ end
67
+
68
+ end
69
+ end
@@ -1,3 +1,3 @@
1
1
  module RMTools
2
- VERSION = '2.0.0'
2
+ VERSION = '2.1.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rmtools
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-29 00:00:00.000000000 Z
12
+ date: 2013-06-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -124,6 +124,8 @@ files:
124
124
  - lib/rmtools/enumerable/hash.rb
125
125
  - lib/rmtools/enumerable/object_space.rb
126
126
  - lib/rmtools/enumerable/range.rb
127
+ - lib/rmtools/enumerable/set.rb
128
+ - lib/rmtools/enumerable/set_ops.rb
127
129
  - lib/rmtools/enumerable/traversal.rb
128
130
  - lib/rmtools/fs.rb
129
131
  - lib/rmtools/fs/dir.rb