optional 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +1 -1
- data/lib/optional/none.rb +4 -0
- data/lib/optional/option.rb +1 -1
- data/lib/optional/option/enumerable.rb +22 -3
- data/lib/optional/some.rb +10 -3
- data/optional.gemspec +1 -1
- data/spec/lib/optional/none_spec.rb +8 -0
- data/spec/lib/optional/option/enumerable_spec.rb +53 -1
- data/spec/lib/optional/some_spec.rb +19 -0
- metadata +1 -1
data/Gemfile.lock
CHANGED
data/lib/optional/none.rb
CHANGED
data/lib/optional/option.rb
CHANGED
@@ -7,13 +7,32 @@ module Option
|
|
7
7
|
self
|
8
8
|
end
|
9
9
|
|
10
|
+
def to_ary
|
11
|
+
to_a
|
12
|
+
end
|
13
|
+
|
14
|
+
def flatten
|
15
|
+
from_array to_ary.flatten
|
16
|
+
end
|
17
|
+
|
18
|
+
def juxt(*methods)
|
19
|
+
map { |v| methods.map { |m| v.send(m) } }
|
20
|
+
end
|
21
|
+
|
22
|
+
def map_through(*methods)
|
23
|
+
methods.reduce(self) { |acc, m| acc.map(&m) }
|
24
|
+
end
|
25
|
+
|
10
26
|
def map
|
11
27
|
from_array super
|
12
28
|
end
|
13
29
|
alias_method :collect, :map
|
14
|
-
alias_method :flat_map, :map
|
15
30
|
alias_method :collect_concat, :map
|
16
31
|
|
32
|
+
def flat_map(&block)
|
33
|
+
map(&block).flatten
|
34
|
+
end
|
35
|
+
|
17
36
|
def detect
|
18
37
|
from_value super
|
19
38
|
end
|
@@ -28,8 +47,8 @@ module Option
|
|
28
47
|
from_array super
|
29
48
|
end
|
30
49
|
|
31
|
-
def reject
|
32
|
-
from_array
|
50
|
+
def reject(*args, &block)
|
51
|
+
from_array to_a.reject(*args, &block)
|
33
52
|
end
|
34
53
|
|
35
54
|
def reduce(*args, &block)
|
data/lib/optional/some.rb
CHANGED
@@ -7,8 +7,8 @@ class Some
|
|
7
7
|
@value = value
|
8
8
|
end
|
9
9
|
|
10
|
-
def each
|
11
|
-
|
10
|
+
def each &block
|
11
|
+
value.is_a?(Array) ? value.each(&block) : block.call(value)
|
12
12
|
end
|
13
13
|
|
14
14
|
def none?(&block)
|
@@ -35,8 +35,15 @@ class Some
|
|
35
35
|
self
|
36
36
|
end
|
37
37
|
|
38
|
+
def merge(other, &block)
|
39
|
+
other.match do |m|
|
40
|
+
m.some { |v| block.nil? ? Some[*value, v] : Some[block.call(value, v)] }
|
41
|
+
m.none { self }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
38
45
|
def to_s
|
39
|
-
"Some[#{value}]"
|
46
|
+
"Some[#{value.inspect}]"
|
40
47
|
end
|
41
48
|
|
42
49
|
def self.[](*values)
|
data/optional.gemspec
CHANGED
@@ -41,4 +41,12 @@ describe None do
|
|
41
41
|
it "prints as None" do
|
42
42
|
None.to_s.should eq "None"
|
43
43
|
end
|
44
|
+
|
45
|
+
it "can be merged with another none" do
|
46
|
+
None.merge(None).should be_none
|
47
|
+
end
|
48
|
+
|
49
|
+
it "can be merged with a some" do
|
50
|
+
None.merge(Some[cat]).should eq Some[cat]
|
51
|
+
end
|
44
52
|
end
|
@@ -3,6 +3,12 @@ require 'spec_helper'
|
|
3
3
|
describe Option::Enumerable do
|
4
4
|
|
5
5
|
let (:cat) { Cat.new("MOGGIE!") }
|
6
|
+
let (:dog) { Dog.new("DOGGIE!") }
|
7
|
+
|
8
|
+
it "makes radek less sad :-(" do
|
9
|
+
Some[4].each { |e| e.should be_a Fixnum }
|
10
|
+
Some[4,5].each { |e| e.should be_a Fixnum }
|
11
|
+
end
|
6
12
|
|
7
13
|
describe "#do" do
|
8
14
|
it "allows ops with side effects to be performed using the value as part of a method chain" do
|
@@ -12,10 +18,16 @@ describe Option::Enumerable do
|
|
12
18
|
end
|
13
19
|
end
|
14
20
|
|
21
|
+
describe "#map_through" do
|
22
|
+
it "allows mapping through multiple methods" do
|
23
|
+
Some[cat, dog].map_through(:name, :chars, :first).should eq Some["M", "D"]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
15
27
|
describe "#map" do
|
16
28
|
|
17
29
|
it "maps a some to a some" do
|
18
|
-
Some[cat].map(&:name).should eq Some["MOGGIE!"]
|
30
|
+
Some[cat, dog].map(&:name).should eq Some["MOGGIE!", "DOGGIE!"]
|
19
31
|
end
|
20
32
|
|
21
33
|
it "also works for collect" do
|
@@ -43,6 +55,32 @@ describe Option::Enumerable do
|
|
43
55
|
end
|
44
56
|
end
|
45
57
|
|
58
|
+
describe "#flat_map" do
|
59
|
+
it 'works as expected over an array of options' do
|
60
|
+
[None, Some[3], None, Some[2]].flat_map do |x|
|
61
|
+
x.map(&:succ)
|
62
|
+
end.should eq [4,3]
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'also works for a some that returns a nested some' do
|
66
|
+
x = Some[stub(y: Some[4])]
|
67
|
+
x.flat_map(&:y).should eq Some[4]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#juxt" do
|
72
|
+
it "collects the results of calling the passed methods" do
|
73
|
+
|
74
|
+
Some[cat].juxt(:name, :class).should eq Some["MOGGIE!", Cat]
|
75
|
+
|
76
|
+
Some[1,2,3].juxt(:pred, :succ).should eq Some[[0, 2], [1, 3], [2, 4]]
|
77
|
+
end
|
78
|
+
|
79
|
+
it "also works for nil" do
|
80
|
+
None.juxt(:name, :class).should be_none
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
46
84
|
describe "#detect" do
|
47
85
|
it "returns none if called on a none" do
|
48
86
|
None.detect{ |pet| pet.name == "MOGGIE!" }.should be_none
|
@@ -116,6 +154,10 @@ describe Option::Enumerable do
|
|
116
154
|
it "also works as inject" do
|
117
155
|
Some[4].inject(:+).should eq 4
|
118
156
|
end
|
157
|
+
|
158
|
+
it "also works within the some" do
|
159
|
+
Some[3,4,5].reduce(:+).should eq 12
|
160
|
+
end
|
119
161
|
end
|
120
162
|
|
121
163
|
describe "#none?" do
|
@@ -131,4 +173,14 @@ describe Option::Enumerable do
|
|
131
173
|
Some[4].reject(&:odd?).should eq Some[4]
|
132
174
|
end
|
133
175
|
end
|
176
|
+
|
177
|
+
describe "#flatten" do
|
178
|
+
it "flattens an array of options" do
|
179
|
+
Some[4].flatten.should eq Some[4]
|
180
|
+
[None, Some[4], Some[2], None].flatten.should eq [4,2]
|
181
|
+
Some[None, Some[4], Some[2], Some[1], None].flatten.should eq Some[4,2,1]
|
182
|
+
Some[None, None].flatten.should eq None
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
134
186
|
end
|
@@ -45,4 +45,23 @@ describe Some do
|
|
45
45
|
it "prints as Some[value]" do
|
46
46
|
Some[4].to_s.should eq "Some[4]"
|
47
47
|
end
|
48
|
+
|
49
|
+
describe '#merge' do
|
50
|
+
it 'can be merged with another some' do
|
51
|
+
Some[3].merge(Some[4]).should eq Some[3,4]
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'can be merged with another merged some' do
|
55
|
+
Some[3, 4].merge(Some[5]).should eq Some[3, 4, 5]
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'can be merged with another some using an operation' do
|
59
|
+
Some[3].merge(Some[4], &:+).should eq Some[7]
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'can be merged with a none' do
|
63
|
+
Some[3].merge(None, &:+).should eq Some[3]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
48
67
|
end
|