optional 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- optional (0.0.1)
4
+ optional (0.0.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,2 +1,30 @@
1
1
  # optional
2
- ### option types to make nils say bye bye
2
+ ### option types to make nils a thing of the past
3
+
4
+ Tony Hoare, inventor of the null reference, calls it his "billion-dollar mistake". You will be no stranger to the ubiquitous `NoMethodError: undefined method 'foo' for nil:NilClass`. But it doesn't have to be this way.
5
+
6
+ There are, crucially, two distinct types of values (or rather lack of values) that are usually, in Ruby, represented as `nil`. There are values that should always be present - and here the fact that they are `nil` actually indicates that an error has occurred somewhere else in your program - and those values that *may or may not be set* - where each case is valid. For example, a person may or may not be wearing a hat.
7
+
8
+ class Hat
9
+ def doff
10
+
11
+ end
12
+ end
13
+
14
+ gwen = Person.create(name: "Gwen", hat: Some[:fedora])
15
+ charlie = Person.create(name: "Charlie", hat: None)
16
+
17
+ class Person
18
+
19
+ def greet
20
+ puts "hello!"
21
+ hat.do { |h| doff h }
22
+ end
23
+
24
+ end
25
+
26
+ gwen.hat.match do |m|
27
+ m.some (:flat_cap) { puts "Hey up!" }
28
+ m.some (:fedora) { |h| puts "*touches brim of #{h} respectfully*" }
29
+ m.none { puts "Hello!" }
30
+ end
data/lib/optional/none.rb CHANGED
@@ -17,8 +17,8 @@ module None
17
17
  raise Option::ValueOfNoneError
18
18
  end
19
19
 
20
- def value_or
21
- yield
20
+ def value_or(default=nil, &block)
21
+ block.nil? ? default : block.call
22
22
  end
23
23
 
24
24
  def & other
@@ -2,6 +2,11 @@ module Option
2
2
  module Enumerable
3
3
  include ::Enumerable
4
4
 
5
+ def do &block
6
+ each &block
7
+ self
8
+ end
9
+
5
10
  def map
6
11
  from_array super
7
12
  end
data/lib/optional/some.rb CHANGED
@@ -15,7 +15,7 @@ class Some
15
15
  block.nil? ? false : super
16
16
  end
17
17
 
18
- def value_or
18
+ def value_or(default=nil)
19
19
  value
20
20
  end
21
21
 
@@ -28,7 +28,7 @@ class Some
28
28
  end
29
29
 
30
30
  def == other
31
- other.some? && value == other.value
31
+ other.is_a?(Some) && value == other.value
32
32
  end
33
33
 
34
34
  def | other
data/optional.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'optional'
3
- s.version = '0.0.2'
3
+ s.version = '0.0.3'
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!"
@@ -19,6 +19,7 @@ describe None do
19
19
 
20
20
  it "does, however, allow you to supply a default in place of a value" do
21
21
  subject.value_or { cat }.should eq cat
22
+ subject.value_or(cat).should eq cat
22
23
  end
23
24
 
24
25
  it "can be anded with another none, yielding none" do
@@ -4,6 +4,14 @@ describe Option::Enumerable do
4
4
 
5
5
  let (:cat) { Cat.new("MOGGIE!") }
6
6
 
7
+ describe "#do" do
8
+ it "allows ops with side effects to be performed using the value as part of a method chain" do
9
+ names = ""
10
+ Some[cat].do { |c| names << c.name }.map(&:name).should eq Some["MOGGIE!"]
11
+ names.should eq "MOGGIE!"
12
+ end
13
+ end
14
+
7
15
  describe "#map" do
8
16
 
9
17
  it "maps a some to a some" do
@@ -23,6 +23,7 @@ describe Some do
23
23
 
24
24
  it "can be passed a default value but won't use it" do
25
25
  Some[cat].value_or { dog }.should eq cat
26
+ Some[cat].value_or(dog).should eq cat
26
27
  end
27
28
 
28
29
  it "can be anded with another some" do
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.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: