hamster 2.0.0 → 3.0.0

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