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 +4 -4
- data/LICENSE +23 -0
- data/lib/hamster/associable.rb +22 -0
- data/lib/hamster/enumerable.rb +9 -0
- data/lib/hamster/hash.rb +81 -4
- data/lib/hamster/list.rb +3 -3
- data/lib/hamster/version.rb +1 -1
- data/spec/lib/hamster/hash/dig_spec.rb +32 -0
- data/spec/lib/hamster/hash/fetch_values_spec.rb +22 -0
- data/spec/lib/hamster/hash/subset_spec.rb +42 -0
- data/spec/lib/hamster/hash/superset_spec.rb +42 -0
- data/spec/lib/hamster/hash/to_proc_spec.rb +39 -0
- data/spec/lib/hamster/hash/values_at_spec.rb +27 -7
- data/spec/lib/hamster/list/multithreading_spec.rb +1 -1
- data/spec/lib/hamster/set/grep_spec.rb +18 -17
- data/spec/lib/hamster/set/grep_v_spec.rb +59 -0
- data/spec/lib/hamster/vector/dig_spec.rb +28 -0
- metadata +20 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c51415b678cde0ed6dccfa4f0add95e7b5d02c6d
|
4
|
+
data.tar.gz: 3c45aa931b32310d8f338f88c53e8df9286c1304
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
data/lib/hamster/associable.rb
CHANGED
@@ -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
|
data/lib/hamster/enumerable.rb
CHANGED
@@ -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.
|
data/lib/hamster/hash.rb
CHANGED
@@ -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`,
|
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
|
-
|
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
|
data/lib/hamster/list.rb
CHANGED
@@ -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::
|
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
|
1594
|
+
end.freeze
|
1595
|
+
end
|
data/lib/hamster/version.rb
CHANGED
@@ -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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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::
|
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
|
-
|
17
|
-
|
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
|
-
|
23
|
+
include_examples "check filtered values"
|
22
24
|
end
|
23
25
|
|
24
|
-
context "with a single item
|
26
|
+
context "with a single item set" do
|
25
27
|
let(:values) { ["A"] }
|
26
28
|
let(:filtered) { ["A"] }
|
27
29
|
|
28
|
-
|
30
|
+
include_examples "check filtered values"
|
29
31
|
end
|
30
32
|
|
31
|
-
context "with a single item
|
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
|
-
|
37
|
+
include_examples "check filtered values"
|
36
38
|
end
|
37
39
|
|
38
|
-
context "with a multi-item
|
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
|
-
|
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
|
-
|
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:
|
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:
|
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
|
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
|
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.
|
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
|