sarah 2.0.1 → 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/HISTORY.txt +11 -0
- data/lib/sarah.rb +82 -46
- data/sarah.gemspec +2 -2
- data/test/15v210.rb +47 -0
- metadata +5 -3
data/HISTORY.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
2014-04-10 Version 2.1.0
|
2
|
+
|
3
|
+
Added :nsq (non-sequential = sparse + random) selector for
|
4
|
+
#length/#size, #keys, #values, #to_a, and #to_h.
|
5
|
+
|
6
|
+
Fixed some deprecated methods to have pre-2.0.0 behavior after
|
7
|
+
2.0.0 changes (i.e. :nsq versus :rnd differences).
|
8
|
+
|
9
|
+
Added #reindex method to reindex sparse values (like #compact!
|
10
|
+
but without nil removal).
|
11
|
+
|
1
12
|
2014-04-01 Version 2.0.1
|
2
13
|
|
3
14
|
Fixed incorrect indexes in "Background" section of comments.
|
data/lib/sarah.rb
CHANGED
@@ -42,27 +42,29 @@
|
|
42
42
|
#
|
43
43
|
# As of version 2.0.0, there are three major data structures internally:
|
44
44
|
# * "seq" - an array of sequentially-indexed values beginning at index 0
|
45
|
-
# (except when negative actual keys are present; see {#negative_mode
|
45
|
+
# (except when negative actual keys are present; see {#negative_mode}
|
46
46
|
# :actual)
|
47
47
|
# * "spr" - a hash representing a sparse array of all other
|
48
48
|
# numerically-indexed values
|
49
49
|
# * "rnd" - a "random access" hash of all non-numerically keyed values
|
50
50
|
#
|
51
51
|
# The sequential and sparse parts are collectively referred to as "ary".
|
52
|
-
#
|
52
|
+
# In some contexts, the non-sequential (sparse and random) parts are
|
53
|
+
# available as "nsq". All three parts together are collectively referred
|
54
|
+
# to as "all".
|
53
55
|
#
|
54
56
|
# Some methods allow you to direct their action to all or specific parts
|
55
57
|
# of the structure by specifying a corrsponding symbol, :seq, :spr, :ary,
|
56
|
-
# :rnd, or :all.
|
58
|
+
# :nsq, :rnd, or :all.
|
57
59
|
#
|
58
60
|
# @author Brian Katzung (briank@kappacs.com), Kappa Computer Solutions, LLC
|
59
61
|
# @copyright 2013-2014 Brian Katzung and Kappa Computer Solutions, LLC
|
60
62
|
# @license MIT License
|
61
|
-
# @version 2.
|
63
|
+
# @version 2.1.0
|
62
64
|
|
63
65
|
class Sarah
|
64
66
|
|
65
|
-
VERSION = "2.
|
67
|
+
VERSION = "2.1.0"
|
66
68
|
|
67
69
|
# Private attributes:
|
68
70
|
# seq [Array] An array of (zero-origin) sequential values.
|
@@ -87,8 +89,15 @@ class Sarah
|
|
87
89
|
|
88
90
|
# @!attribute [r] negative_mode
|
89
91
|
# @return [:actual|:error|:ignore]
|
90
|
-
# How negative indexes/keys are handled.
|
91
|
-
#
|
92
|
+
# How negative indexes/keys are handled.
|
93
|
+
#
|
94
|
+
# :actual - Negative keys represent themselves and are not treated
|
95
|
+
# specially (although delete works like unset in this mode--values
|
96
|
+
# are not reindexed)
|
97
|
+
# :error (default) - Negative keys are interpreted relative to the
|
98
|
+
# end of the array; keys < -@ary_next raise an IndexError
|
99
|
+
# :ignore - Like :error, but keys < -@ary_next are treated as
|
100
|
+
# non-existent on fetch and silently ignored on set
|
92
101
|
attr_reader :negative_mode
|
93
102
|
|
94
103
|
# ##### Class Methods #####
|
@@ -409,6 +418,8 @@ class Sarah
|
|
409
418
|
# Remove nil values in place. In the case of the sequential and sparse
|
410
419
|
# arrays, the remaining values are reindexed sequentially from 0.
|
411
420
|
#
|
421
|
+
# See also {#reindex}.
|
422
|
+
#
|
412
423
|
# @param which [:all|:ary|:rnd] Which data structures are compacted.
|
413
424
|
# @return [Sarah]
|
414
425
|
def compact! (which = :all)
|
@@ -480,7 +491,7 @@ class Sarah
|
|
480
491
|
|
481
492
|
# Deletes each value for which the required block returns true.
|
482
493
|
#
|
483
|
-
# Subsequent values are re-indexed except when {#negative_mode
|
494
|
+
# Subsequent values are re-indexed except when {#negative_mode}
|
484
495
|
# :actual. See also {#unset_if}.
|
485
496
|
#
|
486
497
|
# The block is passed the current value and nil for the sequential
|
@@ -517,8 +528,8 @@ class Sarah
|
|
517
528
|
|
518
529
|
# Delete by value.
|
519
530
|
#
|
520
|
-
# Subsequent values are re-indexed except when {#negative_mode
|
521
|
-
# See also {#unset_value}.
|
531
|
+
# Subsequent values are re-indexed except when {#negative_mode} is
|
532
|
+
# :actual. See also {#unset_value}.
|
522
533
|
#
|
523
534
|
# @param what [Object] The value to be deleted
|
524
535
|
# @param which [:all|:ary|:rnd] The data structures in which to delete.
|
@@ -751,25 +762,30 @@ class Sarah
|
|
751
762
|
|
752
763
|
# Return the random-access hash keys.
|
753
764
|
#
|
765
|
+
# Since 2.0.0 returns only the random-access keys. Since 2.1.0
|
766
|
+
# returns the non-sequential (sparse + random) keys like the
|
767
|
+
# pre-2.0.0 version.
|
768
|
+
#
|
754
769
|
# @return [Array]
|
755
|
-
# @deprecated Please use {#keys} instead.
|
756
|
-
def rnd_keys;
|
770
|
+
# @deprecated Please use {#keys} :nsq or #keys :rnd instead.
|
771
|
+
def rnd_keys; self.keys :nsq; end
|
757
772
|
|
758
773
|
# Return the sequential array keys (indexes).
|
759
774
|
#
|
760
775
|
# @return [Array<Integer>]
|
761
|
-
# @deprecated Please use {#keys} instead.
|
762
|
-
def seq_keys;
|
776
|
+
# @deprecated Please use {#keys} :seq instead.
|
777
|
+
def seq_keys; self.keys :seq; end
|
763
778
|
|
764
779
|
# Return an array of indexes and keys.
|
765
780
|
#
|
766
|
-
# @param which [:all|:ary|:rnd|:seq|:spr] Which indexes and keys
|
767
|
-
# to return. (Since 2.0.0)
|
781
|
+
# @param which [:all|:ary|:nsq|:rnd|:seq|:spr] Which indexes and keys
|
782
|
+
# to return. (Since 2.0.0; :nsq since 2.1.0)
|
768
783
|
# @return [Array]
|
769
784
|
def keys (which = :all)
|
770
785
|
case which
|
771
786
|
when :all then keys(:seq) + keys(:spr) + @rnd.keys
|
772
787
|
when :ary then keys(:seq) + keys(:spr)
|
788
|
+
when :nsq then keys(:spr) + @rnd.keys
|
773
789
|
when :rnd then @rnd.keys
|
774
790
|
when :seq then (0...@seq.size).to_a
|
775
791
|
when :spr then @spr.keys.sort
|
@@ -787,15 +803,18 @@ class Sarah
|
|
787
803
|
|
788
804
|
# Return the random-access hash size.
|
789
805
|
#
|
790
|
-
#
|
806
|
+
# Since 2.1.0, this returns the non-sequential (sparse + random)
|
807
|
+
# hash size, which is more closely reflects the pre-2.0.0 value.
|
808
|
+
#
|
809
|
+
# @deprecated Please use {#size} :rnd or #size :nsq instead.
|
791
810
|
# @return [Integer]
|
792
|
-
def rnd_length;
|
811
|
+
def rnd_length; self.size :nsq; end
|
793
812
|
|
794
813
|
alias_method :rnd_size, :rnd_length
|
795
814
|
|
796
815
|
# Return the sequential array size.
|
797
816
|
#
|
798
|
-
# @deprecated Please use {#size} instead.
|
817
|
+
# @deprecated Please use {#size} :seq instead.
|
799
818
|
# @return [Integer]
|
800
819
|
def seq_length; @seq.size; end
|
801
820
|
|
@@ -803,14 +822,15 @@ class Sarah
|
|
803
822
|
|
804
823
|
# Return the number of stored values (AKA size or length).
|
805
824
|
#
|
806
|
-
# @param which [:all|:ary|:rnd|:seq|:spr] The data structures
|
807
|
-
# for which the (combined) size is to be returned. (Since 2.0.0
|
825
|
+
# @param which [:all|:ary|:nsq|:rnd|:seq|:spr] The data structures
|
826
|
+
# for which the (combined) size is to be returned. (Since 2.0.0;
|
827
|
+
# :nsq since 2.1.0)
|
808
828
|
# @return [Integer]
|
809
829
|
def length (which = :all)
|
810
830
|
size = 0
|
811
831
|
case which when :all, :ary, :seq then size += @seq.size end
|
812
|
-
case which when :all, :ary, :spr then size += @spr.size end
|
813
|
-
case which when :all, :rnd then size += @rnd.size end
|
832
|
+
case which when :all, :ary, :nsq, :spr then size += @spr.size end
|
833
|
+
case which when :all, :nsq, :rnd then size += @rnd.size end
|
814
834
|
size
|
815
835
|
end
|
816
836
|
|
@@ -835,14 +855,6 @@ class Sarah
|
|
835
855
|
|
836
856
|
# Sets the negative mode, the manner in which negative integer
|
837
857
|
# index/key values are handled.
|
838
|
-
#
|
839
|
-
# :actual - Negative keys represent themselves and are not treated
|
840
|
-
# specially (although delete works like unset in this mode--values
|
841
|
-
# are not reindexed)
|
842
|
-
# :error (default) - Negative keys are interpreted relative to the
|
843
|
-
# end of the array; keys < -@ary_next raise an IndexError
|
844
|
-
# :ignore - Like :error, but keys < -@ary_next are treated as
|
845
|
-
# non-existent on fetch and silently ignored on set
|
846
858
|
def negative_mode= (mode)
|
847
859
|
case mode
|
848
860
|
when :actual then @negative_mode = :actual
|
@@ -909,6 +921,22 @@ class Sarah
|
|
909
921
|
# @since 2.0.0
|
910
922
|
def rehash; @spr.rehash; @rnd.rehash; self; end
|
911
923
|
|
924
|
+
# Reindex sparse array values sequentially after any existing
|
925
|
+
# sequential values (or else from index 0).
|
926
|
+
#
|
927
|
+
# This is an immediate in-place operation (not a mode) and is unaffected
|
928
|
+
# by the {#negative_mode}.
|
929
|
+
#
|
930
|
+
# @return [Sarah]
|
931
|
+
# @since 2.1.0
|
932
|
+
def reindex
|
933
|
+
if !@spr.empty?
|
934
|
+
@seq.concat values(:spr)
|
935
|
+
@spr, @ary_first, @ary_next = {}, 0, @seq.size
|
936
|
+
end
|
937
|
+
self
|
938
|
+
end
|
939
|
+
|
912
940
|
# #repeated_combination is not implemented.
|
913
941
|
|
914
942
|
# #repeated_permutation is not implemented.
|
@@ -980,19 +1008,22 @@ class Sarah
|
|
980
1008
|
end
|
981
1009
|
end
|
982
1010
|
|
983
|
-
# Return the sparse array and random-access hash (for
|
1011
|
+
# Return a copy of the merged sparse array and random-access hash (for
|
984
1012
|
# backward-compatibility only).
|
985
1013
|
#
|
1014
|
+
# Through version 2.0.0, this returned the actual underlying random-access
|
1015
|
+
# hash.
|
1016
|
+
#
|
986
1017
|
# @return [Hash]
|
987
|
-
# @deprecated Please use {#to_h} instead.
|
988
|
-
def rnd;
|
1018
|
+
# @deprecated Please use {#to_h} :nsq instead.
|
1019
|
+
def rnd; self.to_h :nsq; end
|
989
1020
|
|
990
1021
|
# Return the sparse array and random-access hash values (for
|
991
1022
|
# backward-compatibility only).
|
992
1023
|
#
|
993
1024
|
# @return [Array]
|
994
|
-
# @deprecated Please use {#values} instead.
|
995
|
-
def rnd_values;
|
1025
|
+
# @deprecated Please use {#values} :nsq or #values :rnd instead.
|
1026
|
+
def rnd_values; self.values :nsq; end
|
996
1027
|
|
997
1028
|
# Rotate sequential and sparse array values into a sequential list.
|
998
1029
|
#
|
@@ -1023,9 +1054,11 @@ class Sarah
|
|
1023
1054
|
|
1024
1055
|
# Return a copy of the sequential array values.
|
1025
1056
|
#
|
1057
|
+
# Prior to 2.0.0, this returned the actual underlying array.
|
1058
|
+
#
|
1026
1059
|
# @return [Array]
|
1027
|
-
# @deprecated Please use {#values} instead.
|
1028
|
-
def seq;
|
1060
|
+
# @deprecated Please use {#values} :seq instead.
|
1061
|
+
def seq; self.values :seq; end
|
1029
1062
|
|
1030
1063
|
alias_method :seq_values, :seq
|
1031
1064
|
|
@@ -1202,27 +1235,29 @@ class Sarah
|
|
1202
1235
|
|
1203
1236
|
# Return all or part of the structure in array representation.
|
1204
1237
|
#
|
1205
|
-
# @param which [:all|:ary|:rnd|:seq|:spr] The parts to represent.
|
1238
|
+
# @param which [:all|:ary|:nsq|:rnd|:seq|:spr] The parts to represent.
|
1239
|
+
# (:nsq since 2.1.0)
|
1206
1240
|
# @since 2.0.0
|
1207
1241
|
def to_a (which = :all)
|
1208
1242
|
ary, hsh = [], {}
|
1209
1243
|
case which when :all, :ary, :seq then ary = @seq end
|
1210
|
-
case which when :all, :ary, :spr then hsh.merge! @spr end
|
1211
|
-
case which when :all, :rnd then hsh.merge! @rnd end
|
1244
|
+
case which when :all, :ary, :nsq, :spr then hsh.merge! @spr end
|
1245
|
+
case which when :all, :nsq, :rnd then hsh.merge! @rnd end
|
1212
1246
|
ary + [hsh]
|
1213
1247
|
end
|
1214
1248
|
|
1215
1249
|
# Return all or part of the structure in hash representation.
|
1216
1250
|
#
|
1217
|
-
# @param which [:all|:ary|:rnd|:seq|:spr] The parts to represent.
|
1251
|
+
# @param which [:all|:ary|:nsq|:rnd|:seq|:spr] The parts to represent.
|
1252
|
+
# (:nsq since 2.1.0)
|
1218
1253
|
# @since 2.0.0
|
1219
1254
|
def to_h (which = :all)
|
1220
1255
|
hsh = {}
|
1221
1256
|
case which when :all, :ary, :seq
|
1222
1257
|
@seq.each_index { |i| hsh[i] = @seq[i] }
|
1223
1258
|
end
|
1224
|
-
case which when :all, :ary, :spr then hsh.merge! @spr end
|
1225
|
-
case which when :all, :rnd then hsh.merge! @rnd end
|
1259
|
+
case which when :all, :ary, :nsq, :spr then hsh.merge! @spr end
|
1260
|
+
case which when :all, :nsq, :rnd then hsh.merge! @rnd end
|
1226
1261
|
hsh
|
1227
1262
|
end
|
1228
1263
|
|
@@ -1346,13 +1381,14 @@ class Sarah
|
|
1346
1381
|
|
1347
1382
|
# Return an array of values.
|
1348
1383
|
#
|
1349
|
-
# @param which [:all|:ary|:rnd|:seq|:spr] Which values to return.
|
1350
|
-
# (Since 2.0.0)
|
1384
|
+
# @param which [:all|:ary|:nsq|:rnd|:seq|:spr] Which values to return.
|
1385
|
+
# (Since 2.0.0; :nsq since 2.1.0)
|
1351
1386
|
# @return [Array]
|
1352
1387
|
def values (which = :all)
|
1353
1388
|
case which
|
1354
1389
|
when :all then @seq + values(:spr) + @rnd.values
|
1355
1390
|
when :ary then @seq + values(:spr)
|
1391
|
+
when :nsq then values(:spr) + @rnd.values
|
1356
1392
|
when :rnd then @rnd.values
|
1357
1393
|
when :seq then Array.new @seq
|
1358
1394
|
when :spr then @spr.values_at(*@spr.keys.sort)
|
data/sarah.gemspec
CHANGED
data/test/15v210.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'sarah'
|
3
|
+
|
4
|
+
# Test changes for version 2.1.0:
|
5
|
+
# Addition of :nsq (non-sequential) selector
|
6
|
+
# #seq returns a copy, not the underlying (actually from 2.0.0)
|
7
|
+
# #rnd returns spr + rnd, not underlying rnd
|
8
|
+
# #reindex
|
9
|
+
|
10
|
+
class TestSarah_15 < MiniTest::Unit::TestCase
|
11
|
+
|
12
|
+
def test_nsq
|
13
|
+
s = Sarah[1, 2, 5 => 'five', :a => ?a]
|
14
|
+
assert_equal 2, s.size(:nsq), 'size :nsq'
|
15
|
+
assert_equal [ 5, :a ], s.keys(:nsq), 'keys :nsq'
|
16
|
+
assert_equal [ 'five', ?a ], s.values(:nsq), 'values :nsq'
|
17
|
+
assert_equal [ { 5 => 'five', :a => ?a } ], s.to_a(:nsq), 'to_a :nsq'
|
18
|
+
assert_equal({ 5 => 'five', :a => ?a }, s.to_h(:nsq), 'to_h :nsq')
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_reindex
|
22
|
+
s = Sarah[1, 2, 5 => 'five', :a => ?a]
|
23
|
+
assert_equal [ 1, 2, { 5 => 'five' } ], s.to_a(:ary), 'before reindex'
|
24
|
+
s.reindex
|
25
|
+
assert_equal [ 1, 2, 'five', {} ], s.to_a(:ary), 'after reindex'
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_rnd
|
29
|
+
s = Sarah[1, 2, 5 => 'five', :a => ?a]
|
30
|
+
assert_equal 2, s.rnd_size, 'rnd_size'
|
31
|
+
assert_equal 1, s.size(:rnd), 'size :rnd'
|
32
|
+
r = s.rnd
|
33
|
+
assert_equal({ 5 => 'five', :a => ?a }, r, 'rnd returns to_h :nsq')
|
34
|
+
r[5], r[:a] = 'six', ?b
|
35
|
+
assert r != s.rnd, "rnd changes don't affect original"
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_seq
|
39
|
+
s = Sarah[1, 2, 5 => 5, :a => :a]
|
40
|
+
seq = s.seq
|
41
|
+
seq[0], seq[1] = 3, 4
|
42
|
+
assert seq != s.seq, "seq changes don't affect original"
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
# END
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 2
|
7
|
-
- 0
|
8
7
|
- 1
|
9
|
-
|
8
|
+
- 0
|
9
|
+
version: 2.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Brian Katzung
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2014-04-
|
17
|
+
date: 2014-04-10 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -50,6 +50,7 @@ files:
|
|
50
50
|
- test/00class.rb
|
51
51
|
- test/08set_ops.rb
|
52
52
|
- test/10count_size.rb
|
53
|
+
- test/15v210.rb
|
53
54
|
- test/13misc.rb
|
54
55
|
- test/05class2.rb
|
55
56
|
- test/06instance2.rb
|
@@ -98,6 +99,7 @@ test_files:
|
|
98
99
|
- test/00class.rb
|
99
100
|
- test/08set_ops.rb
|
100
101
|
- test/10count_size.rb
|
102
|
+
- test/15v210.rb
|
101
103
|
- test/13misc.rb
|
102
104
|
- test/05class2.rb
|
103
105
|
- test/06instance2.rb
|