hamster 2.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 010476a87d79b515fa2da08903f6c36ebffd550e
4
- data.tar.gz: 080ace89fb94c62d9ef29cc3a83c879e64a6b577
3
+ metadata.gz: c51415b678cde0ed6dccfa4f0add95e7b5d02c6d
4
+ data.tar.gz: 3c45aa931b32310d8f338f88c53e8df9286c1304
5
5
  SHA512:
6
- metadata.gz: 596a85aa07273c8912dc6f42a8dcec58684a3eb9ce469f6a1219fd8f3cad242b7b69e72d06b185d77f95496b86b8e197ebedd5cd77e5ce3865fa07c687ee26e2
7
- data.tar.gz: b14a0366601d364dd10a78b9c068c8849fd1471ef01cb0b0656391d2096e5408ba96ad2dcda125e9c99cd7867bf129310bc027995272d865656b1b760b89b3bd
6
+ metadata.gz: 2a3d55da1620b727e7bac47b15751c105ddc7581f36f972adea99c126dd1bd949606ba66e5885c85ac7cbd4fd2298b702df6ab84e61d8b88f03e25aa7e2e1057
7
+ data.tar.gz: 52c5cbfa37e4133a82521928d3532683a46a7f4dc16536cb02302abfa699fd56ce222331213122d80d0bc963588fe4cfd25040df17cd6fcaca3b7312d6eb1434
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Licensing
2
+ =========
3
+
4
+ Copyright (c) 2009-2014 Simon Harris
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -6,6 +6,7 @@ module Hamster
6
6
  #
7
7
  # * `fetch(index, default = (missing_default = true))`
8
8
  # * `put(index, item = yield(get(index)))`
9
+ # * `get(key)`
9
10
  #
10
11
  # See {Vector#fetch}, {Vector#put}, {Hash#fetch}, and {Hash#put} for examples.
11
12
  module Associable
@@ -45,5 +46,26 @@ module Hamster
45
46
  end
46
47
  put(key, new_value)
47
48
  end
49
+
50
+ # Return the value of successively indexing into a collection.
51
+ # If any of the keys is not present in the collection, return `nil`.
52
+ # keys that the Hamster type doesn't understand, raises an argument error
53
+ #
54
+ # @example
55
+ # h = Hamster::Hash[:a => 9, :b => Hamster::Vector['a', 'b'], :e => nil]
56
+ # h.dig(:b, 0) # => "a"
57
+ # h.dig(:b, 5) # => nil
58
+ # h.dig(:b, 0, 0) # => nil
59
+ # h.dig(:b, :a) # ArgumentError
60
+ # @params keys to fetch from the collection
61
+ # @return [Object]
62
+ def dig(key, *rest)
63
+ value = get(key)
64
+ if rest.empty? || value.nil?
65
+ value
66
+ elsif value.respond_to?(:dig)
67
+ value.dig(*rest)
68
+ end
69
+ end
48
70
  end
49
71
  end
@@ -29,6 +29,15 @@ module Hamster
29
29
  result
30
30
  end
31
31
 
32
+ # Search the collection for elements which are not `#===` to `item`. Yield
33
+ # them to the optional code block if provided, and return them as a new
34
+ # collection.
35
+ def grep_v(pattern, &block)
36
+ result = select { |item| !(pattern === item) }
37
+ result = result.map(&block) if block_given?
38
+ result
39
+ end
40
+
32
41
  # Yield all integers from 0 up to, but not including, the number of items in
33
42
  # this collection. For collections which provide indexed access, these are all
34
43
  # the valid, non-negative indices into the collection.
@@ -559,17 +559,34 @@ module Hamster
559
559
  end
560
560
 
561
561
  # Return a {Vector} of the values which correspond to the `wanted` keys.
562
- # If any of the `wanted` keys are not present in this `Hash`, they will be skipped.
562
+ # If any of the `wanted` keys are not present in this `Hash`, `nil` will be
563
+ # placed instead, or the result of the default proc (if one is defined),
564
+ # similar to the behavior of {#get}.
563
565
  #
564
566
  # @example
565
567
  # h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
566
- # h.values_at("B", "A", "D") # => Hamster::Vector[2, 1]
568
+ # h.values_at("B", "A", "D") # => Hamster::Vector[2, 1, nil]
567
569
  #
568
570
  # @param wanted [Array] The keys to retrieve
569
571
  # @return [Vector]
570
572
  def values_at(*wanted)
571
- array = []
572
- wanted.each { |key| array << get(key) if key?(key) }
573
+ array = wanted.map { |key| get(key) }
574
+ Vector.new(array.freeze)
575
+ end
576
+
577
+ # Return a {Vector} of the values which correspond to the `wanted` keys.
578
+ # If any of the `wanted` keys are not present in this `Hash`, raise `KeyError`
579
+ # exception.
580
+ #
581
+ # @example
582
+ # h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
583
+ # h.fetch_values("C", "A") # => Hamster::Vector[3, 1]
584
+ # h.fetch_values("C", "Z") # => KeyError: key not found: "Z"
585
+ #
586
+ # @param wanted [Array] The keys to retrieve
587
+ # @return [Vector]
588
+ def fetch_values(*wanted)
589
+ array = wanted.map { |key| fetch(key) }
573
590
  Vector.new(array.freeze)
574
591
  end
575
592
 
@@ -723,6 +740,50 @@ module Hamster
723
740
  self.eql?(other) || (other.respond_to?(:to_hash) && to_hash.eql?(other.to_hash))
724
741
  end
725
742
 
743
+ # Return true if this `Hash` is a proper superset of `other`, which means
744
+ # all `other`'s keys are contained in this `Hash` with the identical
745
+ # values, and the two hashes are not identical.
746
+ #
747
+ # @param other [Hamster::Hash] The object to compare with
748
+ # @return [Boolean]
749
+ def >(other)
750
+ self != other && self >= other
751
+ end
752
+
753
+ # Return true if this `Hash` is a superset of `other`, which means all
754
+ # `other`'s keys are contained in this `Hash` with the identical values.
755
+ #
756
+ # @param other [Hamster::Hash] The object to compare with
757
+ # @return [Boolean]
758
+ def >=(other)
759
+ other.each do |key, value|
760
+ if self[key] != value
761
+ return false
762
+ end
763
+ end
764
+ true
765
+ end
766
+
767
+ # Return true if this `Hash` is a proper subset of `other`, which means all
768
+ # its keys are contained in `other` with the identical values, and the two
769
+ # hashes are not identical.
770
+ #
771
+ # @param other [Hamster::Hash] The object to compare with
772
+ # @return [Boolean]
773
+ def <(other)
774
+ other > self
775
+ end
776
+
777
+ # Return true if this `Hash` is a subset of `other`, which means all its
778
+ # keys are contained in `other` with the identical values, and the two
779
+ # hashes are not identical.
780
+ #
781
+ # @param other [Hamster::Hash] The object to compare with
782
+ # @return [Boolean]
783
+ def <=(other)
784
+ other >= self
785
+ end
786
+
726
787
  # See `Object#hash`.
727
788
  # @return [Integer]
728
789
  def hash
@@ -782,6 +843,22 @@ module Hamster
782
843
  end
783
844
  alias :to_h :to_hash
784
845
 
846
+ # Return a Proc which accepts a key as an argument and returns the value.
847
+ # The Proc behaves like {#get} (when the key is missing, it returns nil or
848
+ # result of the default proc).
849
+ #
850
+ # @example
851
+ # h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
852
+ # h.to_proc.call("B")
853
+ # # => 2
854
+ # ["A", "C", "X"].map(&h) # The & is short for .to_proc in Ruby
855
+ # # => [1, 3, nil]
856
+ #
857
+ # @return [Proc]
858
+ def to_proc
859
+ lambda { |key| get(key) }
860
+ end
861
+
785
862
  # @return [::Hash]
786
863
  # @private
787
864
  def marshal_dump
@@ -1311,7 +1311,7 @@ module Hamster
1311
1311
  def initialize(&block)
1312
1312
  @head = block # doubles as storage for block while yet unrealized
1313
1313
  @tail = nil
1314
- @atomic = Concurrent::Atomic.new(0) # haven't yet run block
1314
+ @atomic = Concurrent::AtomicReference.new(0) # haven't yet run block
1315
1315
  @size = nil
1316
1316
  end
1317
1317
 
@@ -1591,5 +1591,5 @@ module Hamster
1591
1591
  true
1592
1592
  end
1593
1593
  end
1594
- end
1595
- end.freeze
1594
+ end.freeze
1595
+ end
@@ -1,5 +1,5 @@
1
1
  module Hamster
2
2
  # Current released gem version. Note that master will often have the same
3
3
  # value as a release gem but with different code.
4
- VERSION = "2.0.0"
4
+ VERSION = "3.0.0"
5
5
  end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+ require "hamster/hash"
3
+
4
+ describe Hamster::Hash do
5
+ describe "#dig" do
6
+ let(:h) { H[:a => 9, :b => H[:c => 'a', :d => 4], :e => nil] }
7
+ it "returns the value with one argument to dig" do
8
+ expect(h.dig(:a)).to eq(9)
9
+ end
10
+
11
+ it "returns the value in nested hashes" do
12
+ expect(h.dig(:b, :c)).to eq('a')
13
+ end
14
+
15
+ it "returns nil if the key is not present" do
16
+ expect(h.dig(:f, :foo)).to eq(nil)
17
+ end
18
+
19
+ it "returns nil if you dig out the end of the hash" do
20
+ expect(h.dig(:f, :foo, :bar)).to eq(nil)
21
+ end
22
+
23
+ it "returns nil if a value does not support dig" do
24
+ expect(h.dig(:a, :foo)).to eq(nil)
25
+ end
26
+
27
+ it "returns the correct value when there is a default proc" do
28
+ default_hash = H.new { |k| "#{k}-default" }
29
+ expect(default_hash.dig(:a)).to eq("a-default")
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+ require "hamster/hash"
3
+
4
+ describe Hamster::Hash do
5
+ describe "#fetch_values" do
6
+ context "when the all the requests keys exist" do
7
+ it "returns a vector of values for the given keys" do
8
+ h = H[:a => 9, :b => 'a', :c => -10, :d => nil]
9
+ h.fetch_values.should be_kind_of(Hamster::Vector)
10
+ h.fetch_values.should eql(V.empty)
11
+ h.fetch_values(:a, :d, :b).should be_kind_of(Hamster::Vector)
12
+ h.fetch_values(:a, :d, :b).should eql(V[9, nil, 'a'])
13
+ end
14
+ end
15
+
16
+ context "when the key does not exist" do
17
+ it "raises a KeyError" do
18
+ -> { H["A" => "aye", "C" => "Cee"].fetch_values("A", "B") }.should raise_error(KeyError)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,42 @@
1
+ require "spec_helper"
2
+ require "hamster/hash"
3
+
4
+ RSpec.describe Hamster::Hash do
5
+ describe "#<=" do
6
+ [
7
+ [{}, {}, true],
8
+ [{"A" => 1}, {}, false],
9
+ [{}, {"A" => 1}, true],
10
+ [{"A" => 1}, {"A" => 1}, true],
11
+ [{"A" => 1}, {"A" => 2}, false],
12
+ [{"B" => 2}, {"A" => 1, "B" => 2, "C" => 3}, true],
13
+ [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 2}, false],
14
+ [{"B" => 0}, {"A" => 1, "B" => 2, "C" => 3}, false],
15
+ ].each do |a, b, expected|
16
+ describe "for #{a.inspect} and #{b.inspect}" do
17
+ it "returns #{expected}" do
18
+ expect(H[a] <= H[b]).to eq(expected)
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ describe "#<" do
25
+ [
26
+ [{}, {}, false],
27
+ [{"A" => 1}, {}, false],
28
+ [{}, {"A" => 1}, true],
29
+ [{"A" => 1}, {"A" => 1}, false],
30
+ [{"A" => 1}, {"A" => 2}, false],
31
+ [{"B" => 2}, {"A" => 1, "B" => 2, "C" => 3}, true],
32
+ [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 2}, false],
33
+ [{"B" => 0}, {"A" => 1, "B" => 2, "C" => 3}, false],
34
+ ].each do |a, b, expected|
35
+ describe "for #{a.inspect} and #{b.inspect}" do
36
+ it "returns #{expected}" do
37
+ expect(H[a] < H[b]).to eq(expected)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ require "spec_helper"
2
+ require "hamster/hash"
3
+
4
+ RSpec.describe Hamster::Hash do
5
+ describe "#>=" do
6
+ [
7
+ [{}, {}, true],
8
+ [{"A" => 1}, {}, true],
9
+ [{}, {"A" => 1}, false],
10
+ [{"A" => 1}, {"A" => 1}, true],
11
+ [{"A" => 1}, {"A" => 2}, false],
12
+ [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 2}, true],
13
+ [{"B" => 2}, {"A" => 1, "B" => 2, "C" => 3}, false],
14
+ [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 0}, false],
15
+ ].each do |a, b, expected|
16
+ describe "for #{a.inspect} and #{b.inspect}" do
17
+ it "returns #{expected}" do
18
+ expect(H[a] >= H[b]).to eq(expected)
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ describe "#>" do
25
+ [
26
+ [{}, {}, false],
27
+ [{"A" => 1}, {}, true],
28
+ [{}, {"A" => 1}, false],
29
+ [{"A" => 1}, {"A" => 1}, false],
30
+ [{"A" => 1}, {"A" => 2}, false],
31
+ [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 2}, true],
32
+ [{"B" => 2}, {"A" => 1, "B" => 2, "C" => 3}, false],
33
+ [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 0}, false],
34
+ ].each do |a, b, expected|
35
+ describe "for #{a.inspect} and #{b.inspect}" do
36
+ it "returns #{expected}" do
37
+ expect(H[a] > H[b]).to eq(expected)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+ require "hamster/hash"
3
+
4
+ describe Hamster::Hash do
5
+ describe "#to_proc" do
6
+ context "on Hash without default proc" do
7
+ let(:hash) { H.new("A" => "aye") }
8
+
9
+ it "returns a Proc instance" do
10
+ hash.to_proc.should be_kind_of(Proc)
11
+ end
12
+
13
+ it "returns a Proc that returns the value of an existing key" do
14
+ hash.to_proc.call("A").should == "aye"
15
+ end
16
+
17
+ it "returns a Proc that returns nil for a missing key" do
18
+ hash.to_proc.call("B").should be_nil
19
+ end
20
+ end
21
+
22
+ context "on Hash with a default proc" do
23
+ let(:hash) { H.new("A" => "aye") { |key| "#{key}-VAL" } }
24
+
25
+ it "returns a Proc instance" do
26
+ hash.to_proc.should be_kind_of(Proc)
27
+ end
28
+
29
+ it "returns a Proc that returns the value of an existing key" do
30
+ hash.to_proc.call("A").should == "aye"
31
+ end
32
+
33
+ it "returns a Proc that returns the result of the hash's default proc for a missing key" do
34
+ hash.to_proc.call("B").should == "B-VAL"
35
+ hash.should == H.new("A" => "aye")
36
+ end
37
+ end
38
+ end
39
+ end
@@ -3,12 +3,32 @@ require "hamster/hash"
3
3
 
4
4
  describe Hamster::Hash do
5
5
  describe "#values_at" do
6
- it "returns a vector of values for the given keys" do
7
- h = H[:a => 9, :b => 'a', :c => -10, :d => nil]
8
- h.values_at.should be_kind_of(Hamster::Vector)
9
- h.values_at.should eql(V.empty)
10
- h.values_at(:a, :d, :b).should be_kind_of(Hamster::Vector)
11
- h.values_at(:a, :d, :b).should eql(V[9, nil, 'a'])
6
+ context "on Hash without default proc" do
7
+ let(:hash) { H[:a => 9, :b => 'a', :c => -10, :d => nil] }
8
+
9
+ it "returns an empty vector when no keys are given" do
10
+ hash.values_at.should be_kind_of(Hamster::Vector)
11
+ hash.values_at.should eql(V.empty)
12
+ end
13
+
14
+ it "returns a vector of values for the given keys" do
15
+ hash.values_at(:a, :d, :b).should be_kind_of(Hamster::Vector)
16
+ hash.values_at(:a, :d, :b).should eql(V[9, nil, 'a'])
17
+ end
18
+
19
+ it "fills nil when keys are missing" do
20
+ hash.values_at(:x, :a, :y, :b).should be_kind_of(Hamster::Vector)
21
+ hash.values_at(:x, :a, :y, :b).should eql(V[nil, 9, nil, 'a'])
22
+ end
23
+ end
24
+
25
+ context "on Hash with default proc" do
26
+ let(:hash) { Hamster::Hash.new(:a => 9) { |key| "#{key}-VAL" } }
27
+
28
+ it "fills the result of the default proc when keys are missing" do
29
+ hash.values_at(:x, :a, :y).should be_kind_of(Hamster::Vector)
30
+ hash.values_at(:x, :a, :y).should eql(V['x-VAL', 9, 'y-VAL'])
31
+ end
12
32
  end
13
33
  end
14
- end
34
+ end
@@ -4,7 +4,7 @@ require "concurrent/atomics"
4
4
 
5
5
  describe Hamster::List do
6
6
  it "ensures each node of a lazy list will only be realized on ONE thread, even when accessed by multiple threads" do
7
- counter = Concurrent::Atomic.new(0)
7
+ counter = Concurrent::AtomicReference.new(0)
8
8
  list = (1..10000).to_list.map { |x| counter.update { |count| count + 1 }; x * 2 }
9
9
 
10
10
  threads = 10.times.collect do
@@ -9,50 +9,51 @@ describe Hamster::Set do
9
9
 
10
10
  shared_examples "check filtered values" do
11
11
  it "returns the filtered values" do
12
- expect(grep).to eq(filtered)
12
+ expect(grep).to eq(S[*filtered])
13
13
  end
14
14
  end
15
15
 
16
- shared_examples "check different types of inputs" do
17
- context "with an empty array" do
16
+ context "without a block" do
17
+ let(:block) { nil }
18
+
19
+ context "with an empty set" do
18
20
  let(:values) { [] }
19
21
  let(:filtered) { [] }
20
22
 
21
- shared_examples "check filtered values"
23
+ include_examples "check filtered values"
22
24
  end
23
25
 
24
- context "with a single item array" do
26
+ context "with a single item set" do
25
27
  let(:values) { ["A"] }
26
28
  let(:filtered) { ["A"] }
27
29
 
28
- shared_examples "check filtered values"
30
+ include_examples "check filtered values"
29
31
  end
30
32
 
31
- context "with a single item array that doesn't contain match" do
33
+ context "with a single item set that doesn't contain match" do
32
34
  let(:values) { [1] }
33
35
  let(:filtered) { [] }
34
36
 
35
- shared_examples "check filtered values"
37
+ include_examples "check filtered values"
36
38
  end
37
39
 
38
- context "with a multi-item array where one isn't a match" do
40
+ context "with a multi-item set where one isn't a match" do
39
41
  let(:values) { ["A", 2, "C"] }
40
42
  let(:filtered) { %w[A C] }
41
43
 
42
- shared_examples "check filtered values"
44
+ include_examples "check filtered values"
43
45
  end
44
46
  end
45
47
 
46
- context "without a block" do
47
- let(:block) { nil }
48
-
49
- include_examples "check different types of inputs"
50
- end
51
-
52
48
  describe "with a block" do
53
49
  let(:block) { ->(item) { item.downcase }}
54
50
 
55
- include_examples "check different types of inputs"
51
+ context "processes each matching item with the block" do
52
+ let(:values) { ["A", 2, "C"] }
53
+ let(:filtered) { %w[a c] }
54
+
55
+ include_examples "check filtered values"
56
+ end
56
57
  end
57
58
  end
58
59
  end
@@ -0,0 +1,59 @@
1
+ require "spec_helper"
2
+ require "hamster/set"
3
+
4
+ describe Hamster::Set do
5
+ let(:set) { S[*values] }
6
+
7
+ describe "#grep_v" do
8
+ let(:grep_v) { set.grep_v(String, &block) }
9
+
10
+ shared_examples "check filtered values" do
11
+ it "returns the filtered values" do
12
+ expect(grep_v).to eq(S[*filtered])
13
+ end
14
+ end
15
+
16
+ context "without a block" do
17
+ let(:block) { nil }
18
+
19
+ context "with an empty set" do
20
+ let(:values) { [] }
21
+ let(:filtered) { [] }
22
+
23
+ include_examples "check filtered values"
24
+ end
25
+
26
+ context "with a single item set" do
27
+ let(:values) { ["A"] }
28
+ let(:filtered) { [] }
29
+
30
+ include_examples "check filtered values"
31
+ end
32
+
33
+ context "with a single item set that doesn't contain match" do
34
+ let(:values) { [1] }
35
+ let(:filtered) { [1] }
36
+
37
+ include_examples "check filtered values"
38
+ end
39
+
40
+ context "with a multi-item set where one isn't a match" do
41
+ let(:values) { [2, "C", 4] }
42
+ let(:filtered) { [2, 4] }
43
+
44
+ include_examples "check filtered values"
45
+ end
46
+ end
47
+
48
+ describe "with a block" do
49
+ let(:block) { ->(item) { item + 100 }}
50
+
51
+ context "resulting items are processed with the block" do
52
+ let(:values) { [2, "C", 4] }
53
+ let(:filtered) { [102, 104] }
54
+
55
+ include_examples "check filtered values"
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+ require "hamster/vector"
3
+
4
+ describe Hamster::Vector do
5
+ let(:v) { V[1, 2, V[3, 4]] }
6
+
7
+ describe "#dig" do
8
+ it "returns value at the index with one argument" do
9
+ expect(v.dig(0)).to eq(1)
10
+ end
11
+
12
+ it "returns value at index in nested arrays" do
13
+ expect(v.dig(2, 0)).to eq(3)
14
+ end
15
+
16
+ it "returns nil when indexing deeper than possible" do
17
+ expect(v.dig(0, 0)).to eq(nil)
18
+ end
19
+
20
+ it "returns nil if you index past the end of an array" do
21
+ expect(v.dig(5)).to eq(nil)
22
+ end
23
+
24
+ it "raises a type error when indexing with a key arrays don't understand" do
25
+ expect{ v.dig(:foo) }.to raise_error(ArgumentError)
26
+ end
27
+ end
28
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hamster
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Harris
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-28 00:00:00.000000000 Z
11
+ date: 2016-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.8'
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.8'
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -143,6 +143,7 @@ executables: []
143
143
  extensions: []
144
144
  extra_rdoc_files: []
145
145
  files:
146
+ - LICENSE
146
147
  - lib/hamster.rb
147
148
  - lib/hamster/associable.rb
148
149
  - lib/hamster/core_ext.rb
@@ -203,12 +204,14 @@ files:
203
204
  - spec/lib/hamster/hash/copying_spec.rb
204
205
  - spec/lib/hamster/hash/default_proc_spec.rb
205
206
  - spec/lib/hamster/hash/delete_spec.rb
207
+ - spec/lib/hamster/hash/dig_spec.rb
206
208
  - spec/lib/hamster/hash/each_spec.rb
207
209
  - spec/lib/hamster/hash/each_with_index_spec.rb
208
210
  - spec/lib/hamster/hash/empty_spec.rb
209
211
  - spec/lib/hamster/hash/eql_spec.rb
210
212
  - spec/lib/hamster/hash/except_spec.rb
211
213
  - spec/lib/hamster/hash/fetch_spec.rb
214
+ - spec/lib/hamster/hash/fetch_values_spec.rb
212
215
  - spec/lib/hamster/hash/find_spec.rb
213
216
  - spec/lib/hamster/hash/flat_map_spec.rb
214
217
  - spec/lib/hamster/hash/flatten_spec.rb
@@ -239,9 +242,12 @@ files:
239
242
  - spec/lib/hamster/hash/slice_spec.rb
240
243
  - spec/lib/hamster/hash/sort_spec.rb
241
244
  - spec/lib/hamster/hash/store_spec.rb
245
+ - spec/lib/hamster/hash/subset_spec.rb
246
+ - spec/lib/hamster/hash/superset_spec.rb
242
247
  - spec/lib/hamster/hash/take_spec.rb
243
248
  - spec/lib/hamster/hash/to_a_spec.rb
244
249
  - spec/lib/hamster/hash/to_hash_spec.rb
250
+ - spec/lib/hamster/hash/to_proc_spec.rb
245
251
  - spec/lib/hamster/hash/values_at_spec.rb
246
252
  - spec/lib/hamster/hash/values_spec.rb
247
253
  - spec/lib/hamster/immutable/copying_spec.rb
@@ -355,6 +361,7 @@ files:
355
361
  - spec/lib/hamster/set/first_spec.rb
356
362
  - spec/lib/hamster/set/flatten_spec.rb
357
363
  - spec/lib/hamster/set/grep_spec.rb
364
+ - spec/lib/hamster/set/grep_v_spec.rb
358
365
  - spec/lib/hamster/set/group_by_spec.rb
359
366
  - spec/lib/hamster/set/hash_spec.rb
360
367
  - spec/lib/hamster/set/immutable_spec.rb
@@ -445,6 +452,7 @@ files:
445
452
  - spec/lib/hamster/vector/count_spec.rb
446
453
  - spec/lib/hamster/vector/delete_at_spec.rb
447
454
  - spec/lib/hamster/vector/delete_spec.rb
455
+ - spec/lib/hamster/vector/dig_spec.rb
448
456
  - spec/lib/hamster/vector/drop_spec.rb
449
457
  - spec/lib/hamster/vector/drop_while_spec.rb
450
458
  - spec/lib/hamster/vector/each_index_spec.rb
@@ -526,7 +534,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
526
534
  version: '0'
527
535
  requirements: []
528
536
  rubyforge_project:
529
- rubygems_version: 2.4.3
537
+ rubygems_version: 2.4.8
530
538
  signing_key:
531
539
  specification_version: 4
532
540
  summary: Efficient, immutable, thread-safe collection classes for Ruby
@@ -569,12 +577,14 @@ test_files:
569
577
  - spec/lib/hamster/hash/copying_spec.rb
570
578
  - spec/lib/hamster/hash/default_proc_spec.rb
571
579
  - spec/lib/hamster/hash/delete_spec.rb
580
+ - spec/lib/hamster/hash/dig_spec.rb
572
581
  - spec/lib/hamster/hash/each_spec.rb
573
582
  - spec/lib/hamster/hash/each_with_index_spec.rb
574
583
  - spec/lib/hamster/hash/empty_spec.rb
575
584
  - spec/lib/hamster/hash/eql_spec.rb
576
585
  - spec/lib/hamster/hash/except_spec.rb
577
586
  - spec/lib/hamster/hash/fetch_spec.rb
587
+ - spec/lib/hamster/hash/fetch_values_spec.rb
578
588
  - spec/lib/hamster/hash/find_spec.rb
579
589
  - spec/lib/hamster/hash/flat_map_spec.rb
580
590
  - spec/lib/hamster/hash/flatten_spec.rb
@@ -605,9 +615,12 @@ test_files:
605
615
  - spec/lib/hamster/hash/slice_spec.rb
606
616
  - spec/lib/hamster/hash/sort_spec.rb
607
617
  - spec/lib/hamster/hash/store_spec.rb
618
+ - spec/lib/hamster/hash/subset_spec.rb
619
+ - spec/lib/hamster/hash/superset_spec.rb
608
620
  - spec/lib/hamster/hash/take_spec.rb
609
621
  - spec/lib/hamster/hash/to_a_spec.rb
610
622
  - spec/lib/hamster/hash/to_hash_spec.rb
623
+ - spec/lib/hamster/hash/to_proc_spec.rb
611
624
  - spec/lib/hamster/hash/values_at_spec.rb
612
625
  - spec/lib/hamster/hash/values_spec.rb
613
626
  - spec/lib/hamster/immutable/copying_spec.rb
@@ -721,6 +734,7 @@ test_files:
721
734
  - spec/lib/hamster/set/first_spec.rb
722
735
  - spec/lib/hamster/set/flatten_spec.rb
723
736
  - spec/lib/hamster/set/grep_spec.rb
737
+ - spec/lib/hamster/set/grep_v_spec.rb
724
738
  - spec/lib/hamster/set/group_by_spec.rb
725
739
  - spec/lib/hamster/set/hash_spec.rb
726
740
  - spec/lib/hamster/set/immutable_spec.rb
@@ -811,6 +825,7 @@ test_files:
811
825
  - spec/lib/hamster/vector/count_spec.rb
812
826
  - spec/lib/hamster/vector/delete_at_spec.rb
813
827
  - spec/lib/hamster/vector/delete_spec.rb
828
+ - spec/lib/hamster/vector/dig_spec.rb
814
829
  - spec/lib/hamster/vector/drop_spec.rb
815
830
  - spec/lib/hamster/vector/drop_while_spec.rb
816
831
  - spec/lib/hamster/vector/each_index_spec.rb