null 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data.tar.gz.sig +2 -0
  2. data/lib/null.rb +181 -0
  3. data/test/null.rb +119 -0
  4. metadata +89 -0
  5. metadata.gz.sig +0 -0
@@ -0,0 +1,2 @@
1
+ �'a���"��X�b�!�qc�P{,���]�aR�Н���n����D�B��DKX�%�R��o�0�E�|�� N�~��?��|�"�������z�<��&q��(檦%�_ יK4���Ji��A*�<��Y*�M�dm�@�J>9��_����9W�8@��%�r�]�u -r�?(<HJ*��;y`�ƅ�"1�-��w�O,wa��DŽs
2
+ 6iP����i�d�\\�,6���\����4_��c�[f�����
@@ -0,0 +1,181 @@
1
+ class Object
2
+ # +truthy?+ is +false+ iff we are +nil+, +false+, or an instance of NullClass.
3
+ def truthy?
4
+ true
5
+ end
6
+
7
+ # +falsy?+ is +true+ iff we are +nil+, +false+, or an instance of NullClass.
8
+ def falsy?
9
+ false
10
+ end
11
+
12
+ # This is an alias for +falsy?+.
13
+ def !()
14
+ falsy?
15
+ end
16
+
17
+ # Are we +null+?
18
+ def null?
19
+ false
20
+ end
21
+
22
+ # +null.to_nil?+ returns +nil+; everything else returns +self+.
23
+ def to_nil?()
24
+ self
25
+ end
26
+
27
+ # +obj.tap?()+ is equivalent to +obj.tap()+ unless +obj+ is an instance of
28
+ # NullClass, in which case a block must still be given, but will not be
29
+ # executed.
30
+ def tap? # yield: self
31
+ yield(self)
32
+ self
33
+ end
34
+ end
35
+
36
+ # Make falsy things tell you so.
37
+ module Falsiness
38
+ def truthy? # :nodoc:
39
+ false
40
+ end
41
+
42
+ def falsy? # :nodoc:
43
+ true
44
+ end
45
+
46
+ def !() # :nodoc:
47
+ true
48
+ end
49
+ end
50
+
51
+ # Make boolean logic work with truthiness. Note that this makes these operators
52
+ # asymmetric in that calling boolean operators on +null+ will return +null+.
53
+
54
+ class NilClass
55
+ include Falsiness
56
+ def &(obj) false end
57
+ def |(obj) !!obj end
58
+ def ^(obj) !!obj end
59
+ end
60
+
61
+ class FalseClass
62
+ include Falsiness
63
+ def &(obj) false end
64
+ def |(obj) !!obj end
65
+ def ^(obj) !!obj end
66
+ end
67
+
68
+ class TrueClass
69
+ def &(obj) !!obj end
70
+ def |(obj) true end
71
+ def ^(obj) !obj end
72
+ end
73
+
74
+ # An object including us will convert like +nil+.
75
+ module NillishConversions
76
+ # +[]+
77
+ def to_a() [] end
78
+ alias to_ary to_a
79
+
80
+ # +(0+0i)+
81
+ def to_c() to_i.to_c end
82
+
83
+ # +0.0+
84
+ def to_f() to_i.to_f end
85
+
86
+ # +0+
87
+ def to_i() 0 end
88
+
89
+ # +"null"+
90
+ def to_json() 'null' end
91
+
92
+ # +nil+
93
+ def to_nil?() nil end
94
+
95
+ # +nil+
96
+ def to_param() nil end
97
+
98
+ # +(0/1)+
99
+ def to_r() to_i.to_r end
100
+ alias rationalize to_r
101
+
102
+ # +""+
103
+ def to_s() '' end
104
+ alias to_str to_s
105
+
106
+ # +nil+
107
+ def =~(obj) nil end
108
+ end
109
+
110
+ # Define boolean operators based on truthiness.
111
+ module TruthyBooleanOperators
112
+ def &(obj) truthy? & obj end
113
+ def |(obj) truthy? | obj end
114
+ def ^(obj) truthy? ^ obj end
115
+ end
116
+
117
+ # Define +method_missing+ to return +self+.
118
+ module RecursiveMethodMissing
119
+ # We always return +self+.
120
+ def method_missing(meth, *args)
121
+ self
122
+ end
123
+ end
124
+
125
+ # We implement the Null Object Pattern, i.e. most methods called on us will
126
+ # return +self+. Also, boolean logical operators for +true+, +false+, and +nil+
127
+ # have been redefined so that they depend on the +falsy?+
128
+ class NullClass
129
+ include Falsiness
130
+ include TruthyBooleanOperators
131
+ include RecursiveMethodMissing
132
+
133
+ def to_s() nil end # +""+
134
+ def nil?() true end # :nodoc:
135
+ def null?() true end # :nodoc:
136
+ def empty?() true end # :nodoc:
137
+ def to_nil?() nil end # :nodoc:
138
+ def inspect() 'null' end # +"null"+
139
+ def present?() false end # :nodoc:
140
+
141
+ # Require a block, but don't use it; then return +self+.
142
+ def tap? # :nodoc:
143
+ raise(LocalJumpError, 'no block given') unless block_given?
144
+ self
145
+ end
146
+
147
+ # Make Numeric operations involving +null+ return +null+.
148
+ def coerce(x)
149
+ [null, null]
150
+ end
151
+ end
152
+
153
+ # VoidClass instances act like NullClass instances except
154
+ class VoidClass < NullClass
155
+ include NillishConversions
156
+
157
+ # Become 0 in mathematical operations.
158
+ def coerce(x) to_i.coerce(x) end
159
+ def +(x) x end
160
+ def -(x) -x end
161
+ def *(x) x*self end
162
+ def /(x) to_i/x end
163
+
164
+ # +"void"+
165
+ def inspect
166
+ 'void'
167
+ end
168
+ end
169
+
170
+ NULL = NullClass.new
171
+ # This is an alias for +NULL+, which is an instance of NullObject.
172
+ def null
173
+ NULL
174
+ end
175
+
176
+ VOID = VoidClass.new
177
+ # +void+ is an alias for +VOID+, which is like +null+, except that its +to_*+
178
+ # methods are like +nil+'s.
179
+ def void
180
+ VOID
181
+ end
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/null'
3
+ require 'test/unit'
4
+
5
+ class NullTest < Test::Unit::TestCase
6
+ TRUTHY_TEST_OBJECTS = [1024, 4.20, 4, :twenty, Class.new, Object.new, true,
7
+ method(:method), Array.new, {}, 0, 0.0]
8
+ NULL_TEST_OBJECTS = [null, void, NullClass.new, VoidClass.new]
9
+
10
+ TRUTHY_BOOLEAN_OBJECTS = [true]
11
+ GENERATED_FALSIES = [false, nil]
12
+ RECURSOR_TEST_OBJECTS = []
13
+
14
+ [
15
+ [TruthyBooleanOperators, TRUTHY_BOOLEAN_OBJECTS],
16
+ [Falsiness, GENERATED_FALSIES],
17
+ [RecursiveMethodMissing, RECURSOR_TEST_OBJECTS]
18
+ ].each do |mod, array|
19
+ array << Object.new.extend(mod)
20
+ end
21
+
22
+ ALL_FALSIES = GENERATED_FALSIES + NULL_TEST_OBJECTS
23
+ NON_NULL = TRUTHY_TEST_OBJECTS + TRUTHY_BOOLEAN_OBJECTS + GENERATED_FALSIES +
24
+ RECURSOR_TEST_OBJECTS + [false, nil]
25
+
26
+ def test_truthiness
27
+ TRUTHY_TEST_OBJECTS.each do |truthy|
28
+ msg = "#{truthy} is false"
29
+ assert truthy.truthy?, msg
30
+ assert !truthy.falsy?, msg
31
+ assert !!truthy, msg
32
+ end
33
+
34
+ ALL_FALSIES.each do |falsy|
35
+ msg = "#{falsy} is false"
36
+ assert !falsy.truthy?, msg
37
+ assert falsy.falsy?, msg
38
+ assert !falsy, msg
39
+ end
40
+ end
41
+
42
+ def test_boolean_logic
43
+ TRUTHY_BOOLEAN_OBJECTS.product(ALL_FALSIES).each do |truthy, falsy|
44
+ if truthy.singleton_class.include?(TruthyBooleanOperators)
45
+ assert_equal(true, truthy ^ falsy, "#{truthy} ^ #{falsy} is true")
46
+ assert_equal(true, truthy | falsy, "#{truthy} | #{falsy} is false")
47
+ assert_equal(false, truthy & falsy, "#{truthy} & #{falsy} is false")
48
+ end
49
+
50
+ if falsy.singleton_class.include?(TruthyBooleanOperators)
51
+ assert_equal(true, falsy ^ truthy, "#{falsy} ^ #{truthy} is true")
52
+ assert_equal(true, falsy | truthy, "#{falsy} | #{truthy} is true")
53
+ assert_equal(false, falsy & truthy, "#{falsy} & #{truthy} is false")
54
+ end
55
+ end
56
+ end
57
+
58
+ def test_nil_checks
59
+ assert !nil.null?
60
+ assert nil.nil?
61
+ assert_equal nil, nil.to_nil?()
62
+
63
+ NON_NULL.each do |truthy|
64
+ assert !truthy.null?
65
+
66
+ tap_ran = false
67
+ truthy.tap? do |t|
68
+ tap_ran = true
69
+ assert_equal(truthy, t)
70
+ end
71
+ assert tap_ran
72
+
73
+ assert_equal truthy, truthy.to_nil?()
74
+ end
75
+
76
+ NULL_TEST_OBJECTS.each do |nto|
77
+ assert nto.nil?
78
+ assert nto.null?
79
+ nto.tap? { flunk }
80
+ assert_equal nil, nto.to_nil?()
81
+ end
82
+ end
83
+
84
+ def test_sink
85
+ NULL_TEST_OBJECTS.each do |nto|
86
+ %w{ijfdn edfksliwsauli rdwjsnxs vdsjkg_njdc3ese objectifd kill! doom? fcs
87
+ noki i n self}.each do |func|
88
+ [[5], [1,2], [], Array.new(50, :o), {a: null}].each do |msg|
89
+ assert_equal(nto, nto.send(func, *msg))
90
+ assert_equal(nto, nto.send(func, *msg){flunk})
91
+ end
92
+ end
93
+ end
94
+
95
+ assert_equal null, (5*8+1/1.7)**null
96
+ assert_equal null, null + 5
97
+ assert_equal null, null/0
98
+ assert_equal null, (0 * null) + 5
99
+ end
100
+
101
+ def test_voidness
102
+ assert_equal 48, (void+8)*6
103
+ assert_equal 0, void + 0
104
+
105
+ {
106
+ void.to_a => [],
107
+ void.to_ary => [],
108
+ Array.new(void) => [],
109
+ void.to_c => 0,
110
+ void.to_param => nil,
111
+ void.to_nil? => nil,
112
+ (void =~ '') => nil,
113
+ "#{void}" => '',
114
+ void.rationalize => Rational(0, 1)
115
+ }.each do |real, expected|
116
+ assert_equal(expected, real)
117
+ end
118
+ end
119
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: 'null'
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - katmagic
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain:
12
+ - ! '-----BEGIN CERTIFICATE-----
13
+
14
+ MIIDQDCCAiigAwIBAgIBADANBgkqhkiG9w0BAQUFADBGMRgwFgYDVQQDDA90aGUu
15
+
16
+ bWFnaWNhbC5rYXQxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixk
17
+
18
+ ARkWA2NvbTAeFw0xMTA4MjEyMjMyMDFaFw0xMjA4MjAyMjMyMDFaMEYxGDAWBgNV
19
+
20
+ BAMMD3RoZS5tYWdpY2FsLmthdDEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYK
21
+
22
+ CZImiZPyLGQBGRYDY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
23
+
24
+ pBt20nwjs5W03djpRN6FAbpiio286NHMTk6HhmjV6GZKOi5ZUX5onTnKUg2Vc35z
25
+
26
+ /nK+aIPReyRfBgIcfSjhoXh1A1Dp+2laNgTtU/3eMupruatgORAPCSaG9Ns+HSyR
27
+
28
+ vySbz1QUrwvlvF0qkhhApNQ6dsLl2LMOV3QcluY+Y3CVccOWOSHdQcnAbPuzM9Hf
29
+
30
+ 4ChI4OGL7+DwLA5OK2S5uewRAa2iLkJSN0WugnQlJqMT59GRaqTDOtnYQpiyKEBy
31
+
32
+ QjVPO4LNk7iDsJP22YBrveIzm8/YYRBTU4LTHMEMOyCszrYqD2S1Lwp2rtCJzQCl
33
+
34
+ BA0LtBKrZl5mwZm7qyj+TwIDAQABozkwNzAJBgNVHRMEAjAAMB0GA1UdDgQWBBSm
35
+
36
+ s5arhjp61kmGl6wsmLYkqerdqDALBgNVHQ8EBAMCBLAwDQYJKoZIhvcNAQEFBQAD
37
+
38
+ ggEBAA6cQNQMOPRy4yrj7Nh5Mb9qq8t/8ho/JQvjzVof9qRd+kfKrOoOhXfEO+Rm
39
+
40
+ sWcaOnBCVC4DnZuNDSLygVhCDtMnHjg/JsfO/GBF/QlNTJOO1jkoQiS6w0KARlBm
41
+
42
+ cpXaWg/oMtXJ2PaUga6WkNeXYf9Mad36P4yuGQScjs+WkUUy7DNZvTGReIcCWOR8
43
+
44
+ jteSvvCMobQKGr2DfFOU9Jiddh2FPpz/KOM2ijzwsVNUMUr7R58LoCnQZrZ/YaRW
45
+
46
+ ob6QnVgwqu5SUAKQxlFJ/aKlPMj735z8EogaZC1ZHgg3vkgGGyu57N/8BDDG0TzC
47
+
48
+ Zn3u2leVae/fJ03zYGArhuJKPgc=
49
+
50
+ -----END CERTIFICATE-----
51
+
52
+ '
53
+ date: 2012-02-01 00:00:00.000000000 Z
54
+ dependencies: []
55
+ description: null is null.
56
+ email: the.magical.kat@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - lib/null.rb
62
+ - test/null.rb
63
+ homepage: https://github.com/katmagic/null
64
+ licenses: []
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 1.8.10
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: null is a Null Object.
87
+ test_files:
88
+ - test/null.rb
89
+ has_rdoc:
Binary file