optional 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- optional (0.0.2)
4
+ optional (0.0.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -32,4 +32,8 @@ module None
32
32
  def to_s
33
33
  "None"
34
34
  end
35
+
36
+ def merge other
37
+ other
38
+ end
35
39
  end
@@ -14,7 +14,7 @@ module Option
14
14
  private
15
15
 
16
16
  def from_array(values)
17
- values.empty? ? None : Some[values.first]
17
+ values.empty? ? None : Some[*values]
18
18
  end
19
19
 
20
20
  def from_value(value)
@@ -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 super
50
+ def reject(*args, &block)
51
+ from_array to_a.reject(*args, &block)
33
52
  end
34
53
 
35
54
  def reduce(*args, &block)
@@ -7,8 +7,8 @@ class Some
7
7
  @value = value
8
8
  end
9
9
 
10
- def each
11
- yield value
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)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'optional'
3
- s.version = '0.0.3'
3
+ s.version = '0.0.4'
4
4
  s.date = '2013-04-19'
5
5
  s.summary = "Optional values with pattern matching"
6
6
  s.description = "Make nils go bye bye with Options!"
@@ -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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: optional
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: