setfu 2.1.0 → 3.0.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/lib/setfu.rb CHANGED
@@ -1,13 +1,256 @@
1
1
  require "setfu/version"
2
2
  require "prime"
3
+ require "betterobject"
4
+ require "yieldhelper"
5
+ require "primitive_wrapper"
6
+
7
+ ####
8
+ #### DOC add eql?
9
+ ####
10
+
11
+ class Object
12
+ better_install_as!(:push_unique, :setfu_push_unique)
13
+ better_install_as!(:tag, :setfu_tag)
14
+ better_install_as!(:tag, :setfu_count)
15
+ better_install_as!(:delete_many_at, :setfu_delete_many_at)
16
+ end
17
+
18
+ module Setfu
19
+ def self.bset_elements(ary)
20
+ ary.count.times do |ii|
21
+ ary[ii] = ary[ii].to_bset
22
+ end
23
+ end
24
+ def self.untag_bset_elements(ary)
25
+ ary.count.times do |ii|
26
+ ary[ii].remove_instance_variable :@bo_setfu_tag rescue :never_mind
27
+ ary[ii].remove_instance_variable :@bo_setfu_count rescue :never_mind
28
+ end
29
+ end
30
+ def self.find_tuple(ary, tup_size) # assumes ary is comprised of sets
31
+ candidates = {}
32
+ entropy = 0
33
+ ary.count.times do |ii|
34
+ entropy = ary[ii].entropy > entropy ? ary[ii].entropy : entropy
35
+ unless ary[ii].setfu_count?
36
+ ary[ii].setfu_count = ary[ii].count # store this as #count is slow
37
+ end
38
+ next unless ary[ii].setfu_count == tup_size
39
+ tup = ary[ii].to_i # integer keys are good Hash keys, BitSets are not
40
+ candidates[tup] = 0 # store integer version of set in candidate hash if size matches
41
+ ary.count.times do |jj|
42
+ candidates[tup] +=1 if ary[ii]==ary[jj] # vote count each match
43
+ end
44
+ end
45
+ valid = []
46
+ error = []
47
+ candidates.each_pair do |key,val|
48
+ bset = BitSet.new
49
+ bset.set_bits!(key)
50
+ bset.entropy=entropy
51
+ if val==tup_size
52
+ bset.setfu_tag
53
+ valid.push bset
54
+ elsif val>tup_size
55
+ error.push bset
56
+ end
57
+ end
58
+ group = []
59
+ ary.count.times do |ii|
60
+ next if ary[ii].setfu_tag?
61
+ next if ary[ii].setfu_count > tup_size
62
+ next if ary[ii] <= valid
63
+ next if ary[ii] <= error
64
+ group.push ary[ii]
65
+ end
66
+
67
+ if (tup_size >=3) && (group.count >= tup_size) # stardard match finds smaller things ...
68
+ ptup = []
69
+ group.combination(tup_size) do |combo|
70
+ ta = combo.to_bset
71
+ next unless ta.count == tup_size
72
+ next if ta <= error
73
+ if ta <= ptup # we have an error! There can only be one tuple
74
+ pp = []
75
+ ptup.count.times do |ii|
76
+ pp.push ptup[ii] unless ta==ptup[ii]
77
+ end
78
+ ptup = pp
79
+ error.push ta
80
+ else
81
+ ptup.push ta
82
+ end
83
+ end
84
+ valid.concat ptup
85
+ end
86
+
87
+ # ok everything is in the bin ... what about the shorts of the previous calls?
88
+ # let's just mark what we know for next time ...
89
+ ary.count.times do |ii|
90
+ next if ary[ii].setfu_tag?
91
+ if ary[ii] <= valid
92
+ ary[ii].setfu_tag = :valid
93
+ elsif ary[ii] <= error
94
+ ary[ii].setfu_tag = :error
95
+ end
96
+ end
97
+
98
+ return [valid,error]
99
+ end
100
+
101
+ def self.tuples(ary) # errors include empty sets
102
+ src = []
103
+ valid = []
104
+ error = []
105
+ ary.each do |bs|
106
+ if bs.empty?
107
+ error.setfu_push_unique bs
108
+ else
109
+ src.push bs
110
+ end
111
+ end
112
+ src.count.times do |tup_no|
113
+ rslt = find_tuple(src, tup_no)
114
+ valid.concat rslt[0]
115
+ error.concat rslt[1] # was 2 ... but removed short
116
+ end
117
+ src.count.times do |idx|
118
+ next if src[idx] <= valid
119
+ next if src[idx] <= error
120
+ end
121
+ return [valid,error] if true
122
+ end
123
+
124
+ def self.reduce(ary)
125
+ elms = ary.count
126
+ # process tupples ... first check for errors
127
+ tups = tuples(ary)
128
+ unless (tups.last.empty?)
129
+ ary.setfu_tag = tups.last # tag with broken set items
130
+ return -1 # can't reduce a system of errors
131
+ end
132
+ if (tups.first.empty?)
133
+ return 0
134
+ end
135
+ tups = tups[0].reverse # we only need the good ones.
136
+ reductions = 0
137
+ loop do
138
+ tup = tups.pop
139
+ elms.times do |idx|
140
+ if (tup ** ary[idx]) && !(ary[idx] <= tup)
141
+ ary[idx] -= tup
142
+ reductions += 1
143
+ end
144
+ end
145
+ break if tups.empty?
146
+ end
147
+ return reductions
148
+ end
149
+
150
+ # returns the tuple, else nil
151
+ def self.tuple(ary)
152
+ tup = ary.to_bset
153
+ return nil unless tup.size==ary.count
154
+ return tup if ary.size == 1 # trivial case
155
+ if ary.size==2
156
+ return tup if ary.first==ary.last
157
+ end
158
+ ary.count.times do |idx|
159
+ ta = ary - [ary[idx]]
160
+ return nil if tuple?(ta)
161
+ end
162
+ return tup
163
+ end
164
+
165
+ # the whole thing must be a tuple else false
166
+ def self.tuple?(ary) # from documentation
167
+ return false if ary.empty?
168
+ tup = ary.to_bset
169
+ return false unless tup.size==ary.count
170
+ return true if ary.size == 1 # trivial case
171
+ if ary.size==2
172
+ return true if ary.first==ary.last
173
+ end
174
+ ary.count.times do |idx|
175
+ ta = ary - [ary[idx]]
176
+ return false if tuple?(ta)
177
+ end
178
+ return true
179
+ end
180
+ end
181
+
182
+ class BitSet
183
+ def untag
184
+ BitSet.new | self
185
+ end
186
+ def untag!
187
+ remove_instance_variable :@bo_setfu_tag rescue :never_mind
188
+ remove_instance_variable :@bo_setfu_count rescue :never_mind
189
+ end
190
+ end
191
+
192
+ class Array
193
+ def members_to_bset
194
+ Setfu::bset_elements(self)
195
+ self
196
+ end
197
+ def tuples
198
+ members_to_bset
199
+ rtn = Setfu::tuples(self)
200
+ rtn
201
+ end
202
+ def tuple?
203
+ Setfu::tuple?(self)
204
+ end
205
+ def tuple
206
+ Setfu::tuple(self)
207
+ end
208
+ def reduce_tuples(passes = 1)
209
+ Setfu::bset_elements(self)
210
+ Setfu::untag_bset_elements(self)
211
+ total_count = 0
212
+ loop do
213
+ tc = Setfu::reduce(self)
214
+ if tc < 0
215
+ total_count = -1
216
+ break
217
+ end
218
+ break if tc == 0
219
+ total_count += tc
220
+ passes -= 1
221
+ break if passes <= 0
222
+ end
223
+ total_count
224
+ end
225
+ def untag_bset_elements
226
+ Setfu::untag_bset_elements(self)
227
+ end
228
+ end
3
229
 
4
230
  class BitSet
5
231
  attr_reader :entropy
232
+
233
+ # can't do this ... already using operators for something else
234
+ =begin
235
+ include Comparable
236
+ def <=>(other)
237
+ @bits <=> other.to_bset.to_i
238
+ end
239
+ =end
6
240
 
7
241
  def entropy=(ent) # entropy only gets bigger, just like the universe!
8
242
  @entropy = ent unless @entropy > ent
9
243
  end
10
244
 
245
+ def self.fill(n_elms, start=0)
246
+ set = BitSet.new
247
+ bits = (1 << n_elms) - 1
248
+ set.set_bits!(bits)
249
+ set.entropy=n_elms
250
+ set.inc!(start.ord)
251
+ return set
252
+ end
253
+
11
254
  def self.uppercase_chars
12
255
  set = BitSet.new
13
256
  set.set_bits!(2475880041677272402379145216)
@@ -176,6 +419,10 @@ class BitSet
176
419
  self
177
420
  end
178
421
 
422
+ def size
423
+ count
424
+ end
425
+
179
426
  def inc!(n=1)
180
427
  raise "illegal negative parameter in #inc" if n < 0
181
428
  @entropy += n
@@ -237,7 +484,7 @@ class BitSet
237
484
 
238
485
  def ^(item)
239
486
  rtn = self.dup
240
- if(item.class==BitSet)
487
+ if(item.type_of? BitSet)
241
488
  rtn.set_bits!(rtn.to_i ^ item.to_i)
242
489
  else
243
490
  rtn = BitSet.new(item)
@@ -248,7 +495,7 @@ class BitSet
248
495
 
249
496
  def |(item)
250
497
  rtn = self.dup
251
- if(item.class==BitSet)
498
+ if(item.type_of? BitSet)
252
499
  rtn.set_bits!(rtn.to_i | item.to_i)
253
500
  self.entropy=item.entropy
254
501
  else
@@ -260,7 +507,7 @@ class BitSet
260
507
 
261
508
  def &(item)
262
509
  rtn = self.dup
263
- if(item.class==BitSet)
510
+ if(item.type_of? BitSet)
264
511
  rtn.set_bits!(rtn.to_i & item.to_i)
265
512
  else
266
513
  rtn = BitSet.new(item)
@@ -273,7 +520,7 @@ class BitSet
273
520
  rtn = BitSet.new
274
521
  rtn.entropy = self.entropy
275
522
  a = self.to_i
276
- if(item.class==BitSet)
523
+ if(item.type_of? BitSet)
277
524
  b = item.to_i
278
525
  rtn.entropy = item.entropy
279
526
  else
@@ -295,7 +542,7 @@ class BitSet
295
542
 
296
543
  # comparison operators:
297
544
  def ==(item)
298
- if(item.class==BitSet)
545
+ if(item.type_of? BitSet)
299
546
  rtn = item.to_i == self.to_i
300
547
  else
301
548
  rtn = BitSet.new(item).to_i == self.to_i
@@ -304,7 +551,7 @@ class BitSet
304
551
  end
305
552
 
306
553
  def !=(item)
307
- if(item.class==BitSet)
554
+ if(item.type_of? BitSet)
308
555
  rtn = item.to_i != self.to_i
309
556
  else
310
557
  rtn = BitSet.new(item).to_i != self.to_i
@@ -312,6 +559,10 @@ class BitSet
312
559
  rtn
313
560
  end
314
561
 
562
+ def eql?(item)
563
+ self.==(item)
564
+ end
565
+
315
566
  def set_case(mode=:mode_equal)
316
567
  @mode = mode
317
568
  self
@@ -352,13 +603,15 @@ class BitSet
352
603
  end
353
604
 
354
605
  def add!(items)
355
- if(items.class==BitSet)
606
+ if(items.type_of? BitSet)
356
607
  @bits |= items.to_i
357
608
  entropy = items.entropy
358
- elsif(items.class==Range)
359
- f=items.first.ord
360
- l=items.last.ord
361
- f,l = l,f if f>l
609
+ elsif(items.type_of? Range)
610
+ ran = items.reorder.simplify
611
+ return add!(ran.to_a) unless ran.simple?
612
+ f=ran.first.ord
613
+ l=ran.last.ord
614
+ # f,l = l,f if f>l
362
615
  t = (l-f)+1
363
616
  t = (1 << t)-1
364
617
  @bits |= t << f
@@ -392,14 +645,16 @@ class BitSet
392
645
  def include?(items)
393
646
  return false if items.nil? # sets never include nil
394
647
  return false if @bits == 0 # empty sets include nothing including other empty sets
395
- if(items.class==BitSet)
648
+ if(items.type_of? BitSet)
396
649
  tmp = @bits & items.to_i
397
650
  return false if tmp==0
398
651
  return (tmp) == items.to_i
399
- elsif(items.class==Range)
400
- f=items.first.ord
401
- l=items.last.ord
402
- f,l = l,f if f>l
652
+ elsif(items.type_of? Range)
653
+ ran = items.reorder.simplify
654
+ return(include?(ran.to_a)) unless ran.simple?
655
+ f=ran.first.ord
656
+ l=ran.last.ord
657
+ # f,l = l,f if f>l
403
658
  t = (l-f)+1
404
659
  t = (1 << t)-1
405
660
  t = t << f
@@ -423,6 +678,7 @@ class BitSet
423
678
  end
424
679
 
425
680
  def reverse_each(*prms) # do a benchmark and see which is faster, reverse_each or each
681
+ return Enumerator.enumerate_yields(self, :reverse_each, *prms) unless block_given?
426
682
  int_mode = true
427
683
  set = self.dup
428
684
  prms.each do |prm|
@@ -433,20 +689,13 @@ class BitSet
433
689
  end
434
690
  end
435
691
  ary = set.to_a(int_mode)
436
- unless block_given?
437
- enu = Enumerator.new do |yy|
438
- while !ary.empty?
439
- yy << ary.pop
440
- end
441
- return enu
442
- end
443
- end
444
692
  while !ary.empty?
445
693
  yield ary.pop
446
694
  end
447
695
  end
448
696
 
449
697
  def each(*prms)
698
+ return Enumerator.enumerate_yields(self, :each, *prms) unless block_given?
450
699
  bits = @bits
451
700
  pos = 0
452
701
  stop = nil
@@ -463,21 +712,6 @@ class BitSet
463
712
  chr_mode = !prm
464
713
  end
465
714
  end
466
- unless block_given?
467
- enu = Enumerator.new do |yy|
468
- while bits > 0
469
- if ((bits & 1) == 1)
470
- yy << chr_mode ? pos.chr(Encoding::UTF_8) : pos
471
- end
472
- pos += 1
473
- unless stop.nil?
474
- break if pos > stop
475
- end
476
- bits >>= 1
477
- end # while
478
- end # do
479
- return enu
480
- end # unless
481
715
  while bits > 0
482
716
  if ((bits & 1) == 1)
483
717
  yield chr_mode ? pos.chr(Encoding::UTF_8) : pos
@@ -575,9 +809,9 @@ class BitSet
575
809
  def [](*pset)
576
810
  idx = nil
577
811
  if pset.count==1 # check for single instance inst[5], inst['t']
578
- if pset.first.kind_of? Integer
812
+ if pset.first.type_of? Integer
579
813
  idx = pset.first
580
- elsif pset.first.kind_of? String
814
+ elsif pset.first.type_of? String
581
815
  if pset.first.length == 1
582
816
  idx = pset.first.ord
583
817
  end
@@ -605,8 +839,7 @@ class BitSet
605
839
  end
606
840
 
607
841
  # :array :array_chars :string :set
608
- def rand(elm_count, format = :set)
609
- raise "rand minimum count too low" if elm_count < 1
842
+ def rand(elm_count, format = :bset)
610
843
  ary = self.to_a
611
844
  ary.shuffle!
612
845
  ary = ary[0..(elm_count-1)]
@@ -625,10 +858,36 @@ class BitSet
625
858
  rtn.push elm.chr(Encoding::UTF_8)
626
859
  end
627
860
  return rtn.join ""
628
- else # :set
861
+ else # :bset
629
862
  return ary.to_bset
630
863
  end
631
- end
864
+ end
865
+
866
+ def rand!(elm_count, format = :bset)
867
+ ary = self.to_a
868
+ rna = ary.shuffle[0..(elm_count-1)]
869
+ replace rna.to_bset
870
+ case format
871
+ when :array
872
+ return (ary - rna).shuffle
873
+ when :array_chars
874
+ src = (ary - rna).shuffle
875
+ rtn = []
876
+ src.each do |elm|
877
+ rtn.push elm.chr(Encoding::UTF_8)
878
+ end
879
+ return rtn
880
+ when :string
881
+ src = (ary - rna).shuffle
882
+ rtn = []
883
+ src.each do |elm|
884
+ rtn.push elm.chr(Encoding::UTF_8)
885
+ end
886
+ return rtn.join ""
887
+ else # :bset
888
+ return (ary - rna).to_bset
889
+ end
890
+ end
632
891
 
633
892
  end # end BitSet
634
893
 
@@ -675,7 +934,7 @@ end
675
934
  module SetFuMixinTrippleEqualsOperator
676
935
  alias_method :old_triple_equal4Set, :===
677
936
  def ===(item)
678
- return old_triple_equal4Set(item) unless (item.class==BitSet)
937
+ return old_triple_equal4Set(item) unless (item.type_of? BitSet)
679
938
  return self.to_bset === item
680
939
  end
681
940
  end
@@ -717,13 +976,13 @@ class String
717
976
  include SetFuMixinBinarySubtractOperator
718
977
 
719
978
  def <=(item)
720
- return old_string_lte4set(item) if (item.class==String)
979
+ return old_string_lte4set(item) if (item.type_of? String)
721
980
  a = BitSet.new(self)
722
981
  b = BitSet.new(item)
723
982
  return a <= b
724
983
  end
725
984
  def <(item)
726
- return old_string_lt4set(item) if (item.class==String)
985
+ return old_string_lt4set(item) if (item.type_of? String)
727
986
  a = BitSet.new(self)
728
987
  b = BitSet.new(item)
729
988
  return a < b
@@ -735,27 +994,37 @@ class Array
735
994
  alias_method :old_and_method4set, :&
736
995
  alias_method :old_or_method4set, :|
737
996
 
738
- include SetFuMixinBinaryXorOperator
997
+ # include SetFuMixinBinaryXorOperator
739
998
  include SetFuMixinBinaryIntersectionOperator
740
999
  include SetFuMixinToSetMethod
741
1000
  include SetFuMixinTrippleEqualsOperator
742
1001
  include SetFuMixinBinarySubsetOperator
743
1002
  include SetFuMixinBinaryProperOperator
1003
+
1004
+ def ^(item)
1005
+ if item.type_of? Array
1006
+ return (self | item) - (self & item)
1007
+ else
1008
+ a = BitSet.new(self)
1009
+ b = BitSet.new(item)
1010
+ return a ^ b
1011
+ end
1012
+ end
744
1013
 
745
1014
  def -(item)
746
- return old_subtract_method4set(item) if (item.class==Array)
1015
+ return old_subtract_method4set(item) if (item.type_of? Array)
747
1016
  a = BitSet.new(self)
748
1017
  b = BitSet.new(item)
749
1018
  return a - b
750
1019
  end
751
1020
  def &(item)
752
- return old_and_method4set(item) if (item.class==Array)
1021
+ return old_and_method4set(item) if (item.type_of? Array)
753
1022
  a = BitSet.new(self)
754
1023
  b = BitSet.new(item)
755
1024
  return a & b
756
1025
  end
757
1026
  def |(item)
758
- return old_or_method4set(item) if (item.class==Array)
1027
+ return old_or_method4set(item) if (item.type_of? Array)
759
1028
  a = BitSet.new(self)
760
1029
  b = BitSet.new(item)
761
1030
  return a | b
@@ -1139,6 +1408,27 @@ class BitSet
1139
1408
  @@UTF_UPPER_CASE_DUAL_SET = "".to_bset
1140
1409
  @@UTF_MIXED_CASE_DUAL_SET = "".to_bset
1141
1410
  end
1411
+
1412
+ def self.uppercase_utf_chars(return_set=true)
1413
+ return @@UTF_UPPER_CASE_SET.dup if return_set
1414
+ return @@UTF_UPPER_CASE_CHARS.dup
1415
+ end
1416
+ def self.lowercase_utf_chars(return_set=true)
1417
+ return @@UTF_LOWER_CASE_SET.dup if return_set
1418
+ return @@UTF_LOWER_CASE_CHARS.dup
1419
+ end
1420
+ def self.mixcase_utf_chars(return_set=true)
1421
+ return @@UTF_MIXED_CASE_DUAL_SET.dup if return_set
1422
+ return @@UTF_MIXED_CASE_DUAL_CHARS.dup
1423
+ end
1424
+ def self.dual_uppercase_utf_chars(return_set=true)
1425
+ return @@UTF_UPPER_CASE_DUAL_SET.dup if return_set
1426
+ return @@UTF_UPPER_CASE_DUAL_CHARS.dup
1427
+ end
1428
+ def self.dual_lowercase_utf_chars(return_set=true)
1429
+ return @@UTF_LOWER_CASE_DUAL_SET.dup if return_set
1430
+ return @@UTF_LOWER_CASE_DUAL_CHARS.dup
1431
+ end
1142
1432
 
1143
1433
  def self.modify_utf_sets(*prms)
1144
1434
  flag_add = true
@@ -1146,11 +1436,15 @@ class BitSet
1146
1436
  target_set = nil
1147
1437
  source = nil
1148
1438
  prms.each do |prm|
1149
- if prm.kind_of? String
1439
+ if prm.type_of? String
1150
1440
  source = prm
1151
- elsif prm.kind_of? BitSet
1441
+ elsif prm.type_of? BitSet
1152
1442
  source = prm
1153
- elsif prm.kind_of? Symbol
1443
+ elsif prm.type_of? Array
1444
+ source = prm
1445
+ elsif prm.type_of? Integer
1446
+ source = [prm]
1447
+ elsif prm.type_of? Symbol
1154
1448
  if prm == :rm
1155
1449
  flag_add = false
1156
1450
  elsif prm == :add
@@ -1175,32 +1469,61 @@ class BitSet
1175
1469
  end
1176
1470
  return false if target_chars.nil?
1177
1471
  return false if source.nil?
1178
- return false unless source ** target_set
1179
1472
  if flag_add
1180
1473
  eval("#{target_set} |= source")
1181
- eval("#{target_chars} |= #{target_set}.to_s")
1474
+ eval("#{target_chars} = #{target_set}.to_s")
1182
1475
  else
1183
1476
  eval("#{target_set} -= source")
1184
- eval("#{target_chars} -= #{target_set}.to_s")
1477
+ eval("#{target_chars} = #{target_set}.to_s")
1185
1478
  end
1186
1479
  return true
1187
1480
  end
1481
+
1482
+ def add_lowercase_utf
1483
+ return BitSet.lowercase_utf_chars | self
1484
+ end
1188
1485
 
1189
- def self.uppercase_utf_chars
1190
- return @@UTF_UPPER_CASE_SET.dup
1191
- end
1192
- def self.lowercase_utf_chars
1193
- return @@UTF_LOWER_CASE_SET.dup
1486
+ def add_lowercase_utf!
1487
+ add! BitSet.lowercase_utf_chars
1488
+ self
1489
+ end
1490
+
1491
+ def add_uppercase_utf
1492
+ return BitSet.uppercase_utf_chars | self
1194
1493
  end
1195
- def self.mixcase_utf_chars
1196
- return @@UTF_MIXED_CASE_DUAL_SET.dup
1494
+
1495
+ def add_uppercase_utf!
1496
+ add! BitSet.uppercase_utf_chars
1497
+ self
1197
1498
  end
1198
- def self.dual_uppercase_utf_chars
1199
- return @@UTF_UPPER_CASE_DUAL_SET.dup
1499
+
1500
+ def add_mixcase_utf
1501
+ return BitSet.mixcase_utf_chars | self
1200
1502
  end
1201
- def self.dual_lowercase_utf_chars
1202
- return @@UTF_LOWER_CASE_DUAL_SET.dup
1503
+
1504
+ def add_mixcase_utf!
1505
+ add! BitSet.mixcase_utf_chars
1506
+ self
1507
+ end
1508
+
1509
+ def add_dual_upper_utf
1510
+ return BitSet.dual_uppercase_utf_chars | self
1203
1511
  end
1512
+
1513
+ def add_dual_upper_utf!
1514
+ add! BitSet.dual_uppercase_utf_chars
1515
+ self
1516
+ end
1517
+
1518
+ def add_dual_lower_utf
1519
+ return BitSet.dual_lowercase_utf_chars | self
1520
+ end
1521
+
1522
+ def add_dual_lower_utf!
1523
+ add! BitSet.dual_lowercase_utf_chars
1524
+ self
1525
+ end
1526
+
1204
1527
  end
1205
1528
 
1206
1529
  =begin
data/setfu.gemspec CHANGED
@@ -24,6 +24,10 @@ When characters are used, the ordinate value sets the element bit of the interna
24
24
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
25
25
  spec.require_paths = ["lib"]
26
26
  spec.required_ruby_version = '>= 1.9.1'
27
+ spec.add_runtime_dependency 'pred', '~> 0.1', '>= 0.1.2'
28
+ spec.add_runtime_dependency 'betterobject', '~> 1.2', '>= 1.2.0'
29
+ spec.add_runtime_dependency 'yieldhelper', '~> 0.1', '>= 0.1.0'
30
+ spec.add_runtime_dependency 'primitive_wrapper', '~> 2', '>= 2.0.0'
27
31
 
28
32
  spec.add_development_dependency "bundler", "~> 1.3"
29
33
  spec.add_development_dependency 'rake', '~> 10.1', '>= 10.1.0'