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 +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
|