null_and_void 1.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.
- data/README.md +240 -0
- data/Rakefile +1 -0
- data/lib/null_and_void.rb +7 -0
- data/lib/null_and_void/convertible.rb +54 -0
- data/lib/null_and_void/falsifiable.rb +19 -0
- data/lib/null_and_void/maybe.rb +9 -0
- data/lib/null_and_void/model_support.rb +27 -0
- data/lib/null_and_void/null_object.rb +7 -0
- data/lib/null_and_void/nullified.rb +15 -0
- data/lib/null_and_void/stubbable.rb +7 -0
- data/lib/null_and_void/version.rb +3 -0
- data/spec/convertible_spec.rb +70 -0
- data/spec/falsifiable_spec.rb +26 -0
- data/spec/maybe_spec.rb +20 -0
- data/spec/model_support_spec.rb +31 -0
- data/spec/null_and_void_spec.rb +8 -0
- data/spec/null_object_spec.rb +22 -0
- data/spec/nullified_spec.rb +39 -0
- data/spec/stubbable_spec.rb +14 -0
- metadata +122 -0
data/README.md
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
Null And Void
|
2
|
+
================================
|
3
|
+
|
4
|
+
**Create Null Objects with Ease**
|
5
|
+
|
6
|
+
<img src="http://cdn.memegenerator.net/instances/300x/34275719.jpg" align="right" />
|
7
|
+
|
8
|
+
Using the Null Object pattern in Ruby is rather easy so why create a gem?
|
9
|
+
|
10
|
+
I found myself using the same implementation around the [Null Object
|
11
|
+
pattern](https://en.wikipedia.org/wiki/Null_object_pattern#Ruby) over and over.
|
12
|
+
Rather than duplicating the logic in every one of my projects, I decided to
|
13
|
+
package it up as a gem.
|
14
|
+
|
15
|
+
In the process of doing research to make sure I was implementing this gem the
|
16
|
+
best way possible, I came across [an article by Avdi
|
17
|
+
Grimm](http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness). In the
|
18
|
+
article Avdi brings up a lot of the same ideas I was implementing in my gem.
|
19
|
+
Additionally, he had come up with some [other](#helper-methods)
|
20
|
+
[nicities](#maybies) that I hadn't thought of.
|
21
|
+
|
22
|
+
<br/>
|
23
|
+
<br/>
|
24
|
+
<br/>
|
25
|
+
<br/>
|
26
|
+
<br/>
|
27
|
+
<br/>
|
28
|
+
<br/>
|
29
|
+
|
30
|
+
Installation
|
31
|
+
--------------------------------
|
32
|
+
|
33
|
+
gem install null_and_void
|
34
|
+
|
35
|
+
Usage
|
36
|
+
--------------------------------
|
37
|
+
|
38
|
+
Whenever you want to return a Null Object you can do something like:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
def first_tps_line_item
|
42
|
+
TpsReport.line_items.first || NullAndVoid::NullObject.instance
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
Alternatively, you can [define your own Null Objects](#defineyourownnullobjects)
|
47
|
+
such as:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
def first_tps_line_item
|
51
|
+
TpsReport.line_items.first || NullTpsLineItem.instance
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
If you decide to [use the mixin](#includeintoyourobjectsoptional) you can call
|
56
|
+
the `as_null_object` method on the class and use convention to figure out which
|
57
|
+
Null Object you want:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
def first_tps_line_item
|
61
|
+
TpsReport.line_items.first || TpsLineItem.as_null_object
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
In this case it will return a `NullTpsLineItem` if it's defined and otherwise
|
66
|
+
will return a `NullAndVoid::NullObject`.
|
67
|
+
|
68
|
+
Implementation
|
69
|
+
--------------------------------
|
70
|
+
|
71
|
+
### Method Implementation #####################################################
|
72
|
+
|
73
|
+
With the exception of those defined below, any calls to any methods on a Null
|
74
|
+
Object that inherits from `NullAndVoid::NullObject` will result in itself.
|
75
|
+
|
76
|
+
**Example:**
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
null_object = NullAndVoid::NullObject.instance
|
80
|
+
|
81
|
+
null_object == null_object.foobar # => true
|
82
|
+
```
|
83
|
+
|
84
|
+
### Helper Methods ############################################################
|
85
|
+
|
86
|
+
Many common Ruby methods are implemented as 'noops' such as:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
null_object = NullUser.instance
|
90
|
+
|
91
|
+
null_object.to_i # => 0
|
92
|
+
null_object.to_int # => 0
|
93
|
+
null_object.to_f # => 0.0
|
94
|
+
null_object.to_r # => (0/1)
|
95
|
+
null_object.to_a # => []
|
96
|
+
null_object.to_ary # => []
|
97
|
+
null_object.to_hash # => {}
|
98
|
+
null_object.to_html # => ''
|
99
|
+
null_object.to_json # => ''
|
100
|
+
null_object.to_xml # => ''
|
101
|
+
null_object.to_model # => User.new
|
102
|
+
null_object.to_s # => ''
|
103
|
+
```
|
104
|
+
|
105
|
+
### Falsity ###################################################################
|
106
|
+
|
107
|
+
`NullAndVoid::NullObject` attempts to be falsey whenever possible however it's
|
108
|
+
my opinion that this is an anti-pattern and only the basic attempts are made to
|
109
|
+
make this work. For example:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
null_object = NullAndVoid::NullObject.instance
|
113
|
+
|
114
|
+
!null_object # => true
|
115
|
+
null_object.nil? # => true
|
116
|
+
null_object.blank? # => true
|
117
|
+
null_object.present? # => false
|
118
|
+
```
|
119
|
+
|
120
|
+
### Singleton Implementation ##################################################
|
121
|
+
|
122
|
+
`NullAndVoid::NullObject` is a singleton. All calls to an implementation of it
|
123
|
+
will result in the same object. Therefore:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
NullUser.instance == User.new.as_null_object == User.as_null_object # => true
|
127
|
+
```
|
128
|
+
|
129
|
+
### Define Your Own Null Objects ##############################################
|
130
|
+
|
131
|
+
When implementing a Null Object for a specific class that you own, simply
|
132
|
+
include `NullAndVoid::Nullified` like so:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
require 'null_and_void/nullified'
|
136
|
+
|
137
|
+
class NullUser
|
138
|
+
include NullAndVoid::Nullified
|
139
|
+
|
140
|
+
def admin?
|
141
|
+
false
|
142
|
+
end
|
143
|
+
end
|
144
|
+
```
|
145
|
+
|
146
|
+
### Maybies ###################################################################
|
147
|
+
|
148
|
+
Unfortunately when you're programming in the 'Real World ©" you don't
|
149
|
+
always have control over the API you're using. And sometimes, those APIs,
|
150
|
+
rather than doing the sane thing and always returning the same type no matter
|
151
|
+
what, instead return nils.
|
152
|
+
|
153
|
+
In these situations, you could do this:
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
class Foo
|
157
|
+
def bar
|
158
|
+
call_some_method_that_could_return_nils || NullAndVoid::NullObject.instance
|
159
|
+
end
|
160
|
+
end
|
161
|
+
```
|
162
|
+
|
163
|
+
Or instead, you can simply mixin `NullAndVoid::Mayby` and it will handle that
|
164
|
+
for you. For example:
|
165
|
+
|
166
|
+
```ruby
|
167
|
+
class Foo
|
168
|
+
include NullAndVoid::Maybe
|
169
|
+
|
170
|
+
def bar
|
171
|
+
maybe(call_some_method_that_could_return_nils)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
```
|
175
|
+
|
176
|
+
If you'd rather not mix it into your class, you can also just call it directly:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
class Foo
|
180
|
+
def bar
|
181
|
+
NullAndVoid.maybe(call_some_method_that_could_return_nils)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
186
|
+
### Include Into Your Objects (Optional) ######################################
|
187
|
+
|
188
|
+
You can add Null Object creation to your class by including
|
189
|
+
`NullAndVoid::ModelSupport`.
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
class User
|
193
|
+
include NullAndVoid::ModelSupport
|
194
|
+
|
195
|
+
def admin?
|
196
|
+
type == 'admin'
|
197
|
+
end
|
198
|
+
end
|
199
|
+
```
|
200
|
+
|
201
|
+
This will endow your class with two methods `.as_null_object` and
|
202
|
+
`#as_null_object`. Both of which return either the Null Object for that class
|
203
|
+
(eg `NullUser`) or the generic `NullAndVoid::NullObject`.
|
204
|
+
|
205
|
+
Now, when calling:
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
User.as_null_object
|
209
|
+
```
|
210
|
+
|
211
|
+
or:
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
User.new.as_null_object
|
215
|
+
```
|
216
|
+
|
217
|
+
Will return:
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
NullUser.instance
|
221
|
+
```
|
222
|
+
|
223
|
+
Issues
|
224
|
+
------
|
225
|
+
|
226
|
+
If you have problems, please create a [Github issue](issues).
|
227
|
+
|
228
|
+
Credits
|
229
|
+
-------
|
230
|
+
|
231
|
+

|
232
|
+
|
233
|
+
null_and_void is maintained by [The Kompanee, Ltd.](http://www.thekompanee.com)
|
234
|
+
|
235
|
+
The names and logos for The Kompanee are trademarks of The Kompanee, Ltd.
|
236
|
+
|
237
|
+
License
|
238
|
+
-------
|
239
|
+
|
240
|
+
null_and_void is Copyright © 2013 The Kompanee. It is free software, and may be redistributed under the terms specified in the LICENSE file.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'active_support/inflector/methods'
|
2
|
+
|
3
|
+
module NullAndVoid
|
4
|
+
module Convertible
|
5
|
+
def to_i
|
6
|
+
0
|
7
|
+
end
|
8
|
+
|
9
|
+
alias :to_int :to_i
|
10
|
+
|
11
|
+
def to_f
|
12
|
+
0.0
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_r
|
16
|
+
Rational(0)
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_a
|
20
|
+
Array.new
|
21
|
+
end
|
22
|
+
|
23
|
+
alias :to_ary :to_a
|
24
|
+
|
25
|
+
def to_hash
|
26
|
+
Hash.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_html
|
30
|
+
''
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_json
|
34
|
+
''
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_xml
|
38
|
+
''
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
''
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_model
|
46
|
+
base_path = ActiveSupport::Inflector.demodulize(self.class.name)
|
47
|
+
module_path = ActiveSupport::Inflector.deconstantize(self.class.name)
|
48
|
+
source_model = base_path.gsub(/^Null/, '')
|
49
|
+
source_model_path = "#{module_path}::#{source_model}"
|
50
|
+
|
51
|
+
ActiveSupport::Inflector.constantize(source_model_path).new
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'active_support/inflector/methods'
|
2
|
+
require 'null_and_void/null_object'
|
3
|
+
|
4
|
+
module NullAndVoid
|
5
|
+
module ModelSupport
|
6
|
+
module ClassMethods
|
7
|
+
def as_null_object
|
8
|
+
base_path = ActiveSupport::Inflector.demodulize(self.name)
|
9
|
+
module_path = ActiveSupport::Inflector.deconstantize(self.name)
|
10
|
+
null_object_base = "Null#{base_path}"
|
11
|
+
source_model_path = "#{module_path}::#{null_object_base}"
|
12
|
+
|
13
|
+
ActiveSupport::Inflector.constantize(source_model_path).new
|
14
|
+
rescue NameError
|
15
|
+
NullAndVoid::NullObject.instance
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def as_null_object
|
20
|
+
self.class.as_null_object
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.included(base)
|
24
|
+
base.extend ClassMethods
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'null_and_void/stubbable'
|
3
|
+
require 'null_and_void/convertible'
|
4
|
+
require 'null_and_void/falsifiable'
|
5
|
+
|
6
|
+
module NullAndVoid
|
7
|
+
module Nullified
|
8
|
+
def self.included(base)
|
9
|
+
base.send(:include, Singleton)
|
10
|
+
base.send(:include, Stubbable)
|
11
|
+
base.send(:include, Convertible)
|
12
|
+
base.send(:include, Falsifiable)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/convertible'
|
3
|
+
|
4
|
+
module FooBar
|
5
|
+
class NullObject
|
6
|
+
include NullAndVoid::Convertible
|
7
|
+
end
|
8
|
+
|
9
|
+
class NullBaz
|
10
|
+
include NullAndVoid::Convertible
|
11
|
+
end
|
12
|
+
|
13
|
+
class Object
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe NullAndVoid::Convertible do
|
18
|
+
let(:null_object) { FooBar::NullObject.new }
|
19
|
+
|
20
|
+
it 'is zero when the attempt is made to convert it to an Integer' do
|
21
|
+
null_object.to_i.should be_an Integer
|
22
|
+
null_object.to_i.should be_zero
|
23
|
+
|
24
|
+
null_object.to_int.should be_an Integer
|
25
|
+
null_object.to_int.should be_zero
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'is zero when the attempt is made to convert it to a Float' do
|
29
|
+
null_object.to_f.should be_a Float
|
30
|
+
null_object.to_f.should be_zero
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'is zero when the attempt is made to convert it to a Rational' do
|
34
|
+
null_object.to_r.should be_a Rational
|
35
|
+
null_object.to_r.should be_zero
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'is an empty Array when the attempt is made to convert it to an Array' do
|
39
|
+
null_object.to_a.should eql []
|
40
|
+
null_object.to_ary.should eql []
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'is an empty Hash when the attempt is made to convert it to an Hash' do
|
44
|
+
null_object.to_hash.should eql Hash.new
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'is an empty String when the attempt is made to convert it to HTML' do
|
48
|
+
null_object.to_html.should eql ''
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'is an empty String when the attempt is made to convert it to JSON' do
|
52
|
+
null_object.to_json.should eql ''
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'is an empty String when the attempt is made to convert it to XML' do
|
56
|
+
null_object.to_xml.should eql ''
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'is an empty String when the attempt is made to convert it to a String' do
|
60
|
+
null_object.to_s.should eql ''
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'is the class the Null Object is based on when the attempt is made to convert it to a value object' do
|
64
|
+
null_object.to_model.should be_a FooBar::Object
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'raises an error if the model the Null Object is based on does not exist' do
|
68
|
+
expect { FooBar::NullBaz.new.to_model }.to raise_error NameError
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/falsifiable'
|
3
|
+
|
4
|
+
class NullObject
|
5
|
+
include NullAndVoid::Falsifiable
|
6
|
+
end
|
7
|
+
|
8
|
+
describe NullAndVoid::Falsifiable do
|
9
|
+
let(:null_object) { NullObject.new }
|
10
|
+
|
11
|
+
it 'can be double inverted to be false' do
|
12
|
+
(!!null_object).should be_false
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'is blank' do
|
16
|
+
null_object.should be_blank
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'is nil' do
|
20
|
+
null_object.should be_nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'is not present' do
|
24
|
+
null_object.should_not be_present
|
25
|
+
end
|
26
|
+
end
|
data/spec/maybe_spec.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/maybe'
|
3
|
+
|
4
|
+
class MyObject
|
5
|
+
include NullAndVoid::Maybe
|
6
|
+
end
|
7
|
+
|
8
|
+
describe NullAndVoid::Maybe do
|
9
|
+
context 'when it is passed a nil' do
|
10
|
+
it 'is a null object' do
|
11
|
+
MyObject.new.maybe(nil).should be_a NullAndVoid::NullObject
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when it is passed something other than nil' do
|
16
|
+
it 'is the non-nil object' do
|
17
|
+
MyObject.new.maybe(1).should eql 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/model_support'
|
3
|
+
|
4
|
+
module FooBar
|
5
|
+
class MyNullableModel
|
6
|
+
include NullAndVoid::ModelSupport
|
7
|
+
end
|
8
|
+
|
9
|
+
class NullMyNullableModel
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class NonNullableModel
|
14
|
+
include NullAndVoid::ModelSupport
|
15
|
+
end
|
16
|
+
|
17
|
+
describe NullAndVoid::ModelSupport do
|
18
|
+
let(:model) { FooBar::MyNullableModel.new }
|
19
|
+
|
20
|
+
it 'can convert a model into its Null Object if it exists' do
|
21
|
+
model.as_null_object.should be_a FooBar::NullMyNullableModel
|
22
|
+
end
|
23
|
+
|
24
|
+
it "can convert the model's class into its Null Object if it exists" do
|
25
|
+
model.class.as_null_object.should be_a FooBar::NullMyNullableModel
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'can convert a model into a generic Null Object a model-specific Null Object does not exist' do
|
29
|
+
NonNullableModel.as_null_object.should be_a NullAndVoid::NullObject
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/null_object'
|
3
|
+
|
4
|
+
describe NullAndVoid::NullObject do
|
5
|
+
let(:null_object) { NullAndVoid::NullObject.instance }
|
6
|
+
|
7
|
+
it 'is a singleton' do
|
8
|
+
null_object == NullAndVoid::NullObject.instance
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'is stubbable' do
|
12
|
+
null_object.should be_a NullAndVoid::Stubbable
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'is convertible' do
|
16
|
+
null_object.should be_a NullAndVoid::Convertible
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'is falsifiable' do
|
20
|
+
null_object.should be_a NullAndVoid::Falsifiable
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/null_object'
|
3
|
+
require 'null_and_void/nullified'
|
4
|
+
|
5
|
+
class NullWidget
|
6
|
+
include NullAndVoid::Nullified
|
7
|
+
|
8
|
+
def my_null_object_method
|
9
|
+
'i am null'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe NullAndVoid::Nullified do
|
14
|
+
let(:null_object) { NullWidget.instance }
|
15
|
+
|
16
|
+
it 'is a singleton' do
|
17
|
+
null_object == NullWidget.instance
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'is not a NullAndVoid::NullObject singleton' do
|
21
|
+
null_object != NullAndVoid::NullObject.instance
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'handles undefined methods' do
|
25
|
+
null_object.foobar.should eql NullWidget.instance
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'handles conversions' do
|
29
|
+
null_object.to_a.should eql []
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'is falsifiable' do
|
33
|
+
(!!null_object).should be_false
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'can implement its own methods' do
|
37
|
+
null_object.my_null_object_method.should eql 'i am null'
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rspectacular'
|
2
|
+
require 'null_and_void/stubbable'
|
3
|
+
|
4
|
+
class NullObject
|
5
|
+
include NullAndVoid::Stubbable
|
6
|
+
end
|
7
|
+
|
8
|
+
describe NullAndVoid::Stubbable do
|
9
|
+
let(:null_object) { NullObject.new }
|
10
|
+
|
11
|
+
it 'returns itself for all unknown method calls' do
|
12
|
+
null_object.foobar.should eql null_object
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: null_and_void
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- jfelchner
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '3.1'
|
21
|
+
none: false
|
22
|
+
prerelease: false
|
23
|
+
type: :runtime
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '3.1'
|
29
|
+
none: false
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ~>
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '2.12'
|
37
|
+
none: false
|
38
|
+
prerelease: false
|
39
|
+
type: :development
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '2.12'
|
45
|
+
none: false
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspectacular
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ~>
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0.7'
|
53
|
+
none: false
|
54
|
+
prerelease: false
|
55
|
+
type: :development
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0.7'
|
61
|
+
none: false
|
62
|
+
description: Makes generating Null Objects easy.
|
63
|
+
email: accounts+git@thekompanee.com
|
64
|
+
executables: []
|
65
|
+
extensions: []
|
66
|
+
extra_rdoc_files:
|
67
|
+
- README.md
|
68
|
+
files:
|
69
|
+
- lib/null_and_void/convertible.rb
|
70
|
+
- lib/null_and_void/falsifiable.rb
|
71
|
+
- lib/null_and_void/maybe.rb
|
72
|
+
- lib/null_and_void/model_support.rb
|
73
|
+
- lib/null_and_void/null_object.rb
|
74
|
+
- lib/null_and_void/nullified.rb
|
75
|
+
- lib/null_and_void/stubbable.rb
|
76
|
+
- lib/null_and_void/version.rb
|
77
|
+
- lib/null_and_void.rb
|
78
|
+
- Rakefile
|
79
|
+
- README.md
|
80
|
+
- spec/convertible_spec.rb
|
81
|
+
- spec/falsifiable_spec.rb
|
82
|
+
- spec/maybe_spec.rb
|
83
|
+
- spec/model_support_spec.rb
|
84
|
+
- spec/null_and_void_spec.rb
|
85
|
+
- spec/null_object_spec.rb
|
86
|
+
- spec/nullified_spec.rb
|
87
|
+
- spec/stubbable_spec.rb
|
88
|
+
homepage: https://github.com/jfelchner/null_and_void
|
89
|
+
licenses: []
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options:
|
92
|
+
- --charset = UTF-8
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
none: false
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
none: false
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project: null_and_void
|
109
|
+
rubygems_version: 1.8.25
|
110
|
+
signing_key:
|
111
|
+
specification_version: 3
|
112
|
+
summary: Easy Null Objects
|
113
|
+
test_files:
|
114
|
+
- spec/convertible_spec.rb
|
115
|
+
- spec/falsifiable_spec.rb
|
116
|
+
- spec/maybe_spec.rb
|
117
|
+
- spec/model_support_spec.rb
|
118
|
+
- spec/null_and_void_spec.rb
|
119
|
+
- spec/null_object_spec.rb
|
120
|
+
- spec/nullified_spec.rb
|
121
|
+
- spec/stubbable_spec.rb
|
122
|
+
has_rdoc:
|