kind 3.1.0 → 5.2.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.
- checksums.yaml +4 -4
- data/.tool-versions +1 -0
- data/.travis.sh +67 -12
- data/.travis.yml +7 -5
- data/CHANGELOG.md +1647 -0
- data/Gemfile +22 -7
- data/README.md +920 -486
- data/kind.gemspec +1 -1
- data/lib/kind.rb +2 -314
- data/lib/kind/__lib__/attributes.rb +66 -0
- data/lib/kind/__lib__/kind.rb +71 -0
- data/lib/kind/__lib__/undefined.rb +14 -0
- data/lib/kind/action.rb +92 -0
- data/lib/kind/active_model/validation.rb +3 -4
- data/lib/kind/basic.rb +73 -0
- data/lib/kind/basic/error.rb +29 -0
- data/lib/kind/{undefined.rb → basic/undefined.rb} +8 -1
- data/lib/kind/dig.rb +31 -11
- data/lib/kind/either.rb +30 -0
- data/lib/kind/either/left.rb +29 -0
- data/lib/kind/either/methods.rb +17 -0
- data/lib/kind/either/monad.rb +65 -0
- data/lib/kind/either/monad/wrapper.rb +19 -0
- data/lib/kind/either/right.rb +38 -0
- data/lib/kind/empty.rb +4 -10
- data/lib/kind/empty/constant.rb +7 -0
- data/lib/kind/enum.rb +63 -0
- data/lib/kind/enum/item.rb +40 -0
- data/lib/kind/enum/methods.rb +72 -0
- data/lib/kind/function.rb +47 -0
- data/lib/kind/functional.rb +89 -0
- data/lib/kind/functional/action.rb +89 -0
- data/lib/kind/immutable_attributes.rb +34 -0
- data/lib/kind/immutable_attributes/initializer.rb +70 -0
- data/lib/kind/immutable_attributes/reader.rb +38 -0
- data/lib/kind/maybe.rb +35 -159
- data/lib/kind/maybe/methods.rb +21 -0
- data/lib/kind/maybe/monad.rb +82 -0
- data/lib/kind/maybe/monad/wrapper.rb +19 -0
- data/lib/kind/maybe/none.rb +50 -0
- data/lib/kind/maybe/some.rb +132 -0
- data/lib/kind/maybe/typed.rb +35 -0
- data/lib/kind/maybe/wrapper.rb +37 -0
- data/lib/kind/monad.rb +22 -0
- data/lib/kind/monads.rb +5 -0
- data/lib/kind/objects.rb +17 -0
- data/lib/kind/objects/basic_object.rb +45 -0
- data/lib/kind/objects/modules.rb +32 -0
- data/lib/kind/objects/modules/core/array.rb +19 -0
- data/lib/kind/objects/modules/core/class.rb +13 -0
- data/lib/kind/objects/modules/core/comparable.rb +13 -0
- data/lib/kind/objects/modules/core/enumerable.rb +13 -0
- data/lib/kind/objects/modules/core/enumerator.rb +13 -0
- data/lib/kind/objects/modules/core/file.rb +13 -0
- data/lib/kind/objects/modules/core/float.rb +13 -0
- data/lib/kind/objects/modules/core/hash.rb +19 -0
- data/lib/kind/objects/modules/core/integer.rb +13 -0
- data/lib/kind/objects/modules/core/io.rb +13 -0
- data/lib/kind/objects/modules/core/method.rb +13 -0
- data/lib/kind/objects/modules/core/module.rb +17 -0
- data/lib/kind/objects/modules/core/numeric.rb +13 -0
- data/lib/kind/objects/modules/core/proc.rb +13 -0
- data/lib/kind/objects/modules/core/queue.rb +14 -0
- data/lib/kind/objects/modules/core/range.rb +13 -0
- data/lib/kind/objects/modules/core/regexp.rb +13 -0
- data/lib/kind/objects/modules/core/string.rb +19 -0
- data/lib/kind/objects/modules/core/struct.rb +13 -0
- data/lib/kind/objects/modules/core/symbol.rb +13 -0
- data/lib/kind/objects/modules/core/time.rb +13 -0
- data/lib/kind/objects/modules/custom/boolean.rb +19 -0
- data/lib/kind/objects/modules/custom/callable.rb +19 -0
- data/lib/kind/objects/modules/custom/lambda.rb +19 -0
- data/lib/kind/objects/modules/stdlib/open_struct.rb +15 -0
- data/lib/kind/objects/modules/stdlib/set.rb +19 -0
- data/lib/kind/objects/nil.rb +17 -0
- data/lib/kind/objects/not_nil.rb +13 -0
- data/lib/kind/objects/object.rb +56 -0
- data/lib/kind/objects/respond_to.rb +30 -0
- data/lib/kind/objects/union_type.rb +44 -0
- data/lib/kind/presence.rb +35 -0
- data/lib/kind/result.rb +31 -0
- data/lib/kind/result/abstract.rb +53 -0
- data/lib/kind/result/failure.rb +31 -0
- data/lib/kind/result/methods.rb +17 -0
- data/lib/kind/result/monad.rb +69 -0
- data/lib/kind/result/monad/wrapper.rb +19 -0
- data/lib/kind/result/success.rb +40 -0
- data/lib/kind/try.rb +46 -0
- data/lib/kind/validator.rb +112 -1
- data/lib/kind/version.rb +1 -1
- data/test.sh +4 -4
- metadata +81 -13
- data/lib/kind/active_model/kind_validator.rb +0 -96
- data/lib/kind/checker.rb +0 -15
- data/lib/kind/checker/factory.rb +0 -35
- data/lib/kind/checker/protocol.rb +0 -73
- data/lib/kind/error.rb +0 -19
- data/lib/kind/is.rb +0 -19
- data/lib/kind/of.rb +0 -11
- data/lib/kind/types.rb +0 -115
data/kind.gemspec
CHANGED
|
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
|
10
10
|
spec.description = %q{A simple type system (at runtime) for Ruby - free of dependencies.}
|
|
11
11
|
spec.homepage = 'https://github.com/serradura/kind'
|
|
12
12
|
spec.license = 'MIT'
|
|
13
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.
|
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.1.0')
|
|
14
14
|
|
|
15
15
|
spec.metadata['homepage_uri'] = spec.homepage
|
|
16
16
|
spec.metadata['source_code_uri'] = 'https://github.com/serradura/kind'
|
data/lib/kind.rb
CHANGED
|
@@ -1,316 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'kind/
|
|
4
|
-
|
|
5
|
-
require 'ostruct'
|
|
6
|
-
|
|
7
|
-
require 'kind/empty'
|
|
8
|
-
require 'kind/undefined'
|
|
9
|
-
require 'kind/checker'
|
|
10
|
-
require 'kind/maybe'
|
|
11
|
-
|
|
12
|
-
require 'kind/error'
|
|
13
|
-
require 'kind/of'
|
|
14
|
-
require 'kind/is'
|
|
15
|
-
require 'kind/types'
|
|
16
|
-
|
|
17
|
-
module Kind
|
|
18
|
-
WRONG_NUMBER_OF_ARGUMENTS = 'wrong number of arguments (given 1, expected 2)'.freeze
|
|
19
|
-
|
|
20
|
-
private_constant :WRONG_NUMBER_OF_ARGUMENTS
|
|
21
|
-
|
|
22
|
-
def self.is(expected = Undefined, object = Undefined)
|
|
23
|
-
return Is if Undefined == expected && Undefined == object
|
|
24
|
-
|
|
25
|
-
return Kind::Is.(expected, object) if Undefined != object
|
|
26
|
-
|
|
27
|
-
raise ArgumentError, WRONG_NUMBER_OF_ARGUMENTS
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def self.of(kind = Undefined, object = Undefined)
|
|
31
|
-
return Of if Undefined == kind && Undefined == object
|
|
32
|
-
|
|
33
|
-
return Kind::Of.(kind, object) if Undefined != object
|
|
34
|
-
|
|
35
|
-
Kind::Checker::Factory.create(kind)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def self.of?(kind, *args)
|
|
39
|
-
Kind.of(kind).instance?(*args)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# --------------------- #
|
|
43
|
-
# Special type checkers #
|
|
44
|
-
# --------------------- #
|
|
45
|
-
|
|
46
|
-
module Is
|
|
47
|
-
def self.Class(value)
|
|
48
|
-
value.kind_of?(::Class)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def self.Module(value)
|
|
52
|
-
::Module == value || (value.is_a?(::Module) && !self.Class(value))
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def self.Boolean(value)
|
|
56
|
-
Kind.of.Class(value) <= TrueClass || value <= FalseClass
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def self.Callable(value)
|
|
60
|
-
value.respond_to?(:call)
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
module Of
|
|
65
|
-
# -- Class
|
|
66
|
-
|
|
67
|
-
def self.Class(object = Undefined)
|
|
68
|
-
return Class if Undefined == object
|
|
69
|
-
|
|
70
|
-
self.call(::Class, object)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
const_set(:Class, ::Module.new do
|
|
74
|
-
extend Checker::Protocol
|
|
75
|
-
|
|
76
|
-
def self.__kind; ::Class; end
|
|
77
|
-
|
|
78
|
-
def self.class?(value); Kind::Is.Class(value); end
|
|
79
|
-
|
|
80
|
-
def self.__is_instance__(value); class?(value); end
|
|
81
|
-
end)
|
|
82
|
-
|
|
83
|
-
def self.Class?(*args)
|
|
84
|
-
Kind::Of::Class.instance?(*args)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# -- Module
|
|
88
|
-
|
|
89
|
-
def self.Module(object = Undefined)
|
|
90
|
-
return Module if Undefined == object
|
|
91
|
-
|
|
92
|
-
self.call(::Module, object)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
const_set(:Module, ::Module.new do
|
|
96
|
-
extend Checker::Protocol
|
|
97
|
-
|
|
98
|
-
def self.__kind_undefined(value)
|
|
99
|
-
__kind_error(Kind::Undefined) if Kind::Undefined == value
|
|
100
|
-
|
|
101
|
-
yield
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def self.__kind_error(value)
|
|
105
|
-
raise Kind::Error.new('Module'.freeze, value)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def self.__kind_of(value)
|
|
109
|
-
return value if Kind::Is.Module(value)
|
|
110
|
-
|
|
111
|
-
__kind_error(value)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def self.__kind; ::Module; end
|
|
115
|
-
|
|
116
|
-
def self.class?(value); Kind::Is.Module(value); end
|
|
117
|
-
|
|
118
|
-
def self.instance(value, options = Empty::HASH)
|
|
119
|
-
default = options[:or]
|
|
120
|
-
|
|
121
|
-
if ::Kind::Maybe::Value.none?(default)
|
|
122
|
-
__kind_undefined(value) { __kind_of(value) }
|
|
123
|
-
else
|
|
124
|
-
return value if Kind::Undefined != value && instance?(value)
|
|
125
|
-
|
|
126
|
-
__kind_undefined(default) { __kind_of(default) }
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def self.__is_instance__(value); class?(value); end
|
|
131
|
-
end)
|
|
132
|
-
|
|
133
|
-
def self.Module?(*args)
|
|
134
|
-
Kind::Of::Module.instance?(*args)
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# -- Boolean
|
|
138
|
-
|
|
139
|
-
def self.Boolean(object = Undefined, options = Empty::HASH)
|
|
140
|
-
default = options[:or]
|
|
141
|
-
|
|
142
|
-
return Kind::Of::Boolean if Undefined == object && default.nil?
|
|
143
|
-
|
|
144
|
-
bool = object.nil? ? default : object
|
|
145
|
-
|
|
146
|
-
return bool if bool.is_a?(::TrueClass) || bool.is_a?(::FalseClass)
|
|
147
|
-
|
|
148
|
-
raise Kind::Error.new('Boolean'.freeze, bool)
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
const_set(:Boolean, ::Module.new do
|
|
152
|
-
extend Checker::Protocol
|
|
153
|
-
|
|
154
|
-
def self.__kind; [TrueClass, FalseClass].freeze; end
|
|
155
|
-
|
|
156
|
-
def self.class?(value); Kind.is.Boolean(value); end
|
|
157
|
-
|
|
158
|
-
def self.instance(value, options= Empty::HASH)
|
|
159
|
-
default = options[:or]
|
|
160
|
-
|
|
161
|
-
if ::Kind::Maybe::Value.none?(default)
|
|
162
|
-
__kind_undefined(value) { Kind::Of::Boolean(value) }
|
|
163
|
-
else
|
|
164
|
-
return value if Kind::Undefined != value && instance?(value)
|
|
165
|
-
|
|
166
|
-
__kind_undefined(default) { Kind::Of::Boolean(default) }
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
def self.__kind_undefined(value)
|
|
171
|
-
if Kind::Undefined == value
|
|
172
|
-
raise Kind::Error.new('Boolean'.freeze, Kind::Undefined)
|
|
173
|
-
else
|
|
174
|
-
yield
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
def self.__is_instance__(value);
|
|
179
|
-
value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
def self.or_undefined(value)
|
|
183
|
-
result = or_nil(value)
|
|
184
|
-
result.nil? ? Kind::Undefined : result
|
|
185
|
-
end
|
|
186
|
-
end)
|
|
187
|
-
|
|
188
|
-
def self.Boolean?(*args)
|
|
189
|
-
Kind::Of::Boolean.instance?(*args)
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
# -- Lambda
|
|
193
|
-
|
|
194
|
-
def self.Lambda(object = Undefined, options = Empty::HASH)
|
|
195
|
-
default = options[:or]
|
|
196
|
-
|
|
197
|
-
return Kind::Of::Lambda if Undefined == object && default.nil?
|
|
198
|
-
|
|
199
|
-
func = object || default
|
|
200
|
-
|
|
201
|
-
return func if func.is_a?(::Proc) && func.lambda?
|
|
202
|
-
|
|
203
|
-
raise Kind::Error.new('Lambda'.freeze, func)
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
const_set(:Lambda, ::Module.new do
|
|
207
|
-
extend Checker::Protocol
|
|
208
|
-
|
|
209
|
-
def self.__kind; ::Proc; end
|
|
210
|
-
|
|
211
|
-
def self.instance(value, options = Empty::HASH)
|
|
212
|
-
default = options[:or]
|
|
213
|
-
|
|
214
|
-
if ::Kind::Maybe::Value.none?(default)
|
|
215
|
-
__kind_undefined(value) { Kind::Of::Lambda(value) }
|
|
216
|
-
else
|
|
217
|
-
return value if Kind::Undefined != value && instance?(value)
|
|
218
|
-
|
|
219
|
-
__kind_undefined(default) { Kind::Of::Lambda(default) }
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
def self.__kind_undefined(value)
|
|
224
|
-
if Kind::Undefined == value
|
|
225
|
-
raise Kind::Error.new('Lambda'.freeze, Kind::Undefined)
|
|
226
|
-
else
|
|
227
|
-
yield
|
|
228
|
-
end
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
def self.__is_instance__(value)
|
|
232
|
-
value.is_a?(__kind) && value.lambda?
|
|
233
|
-
end
|
|
234
|
-
end)
|
|
235
|
-
|
|
236
|
-
def self.Lambda?(*args)
|
|
237
|
-
Kind::Of::Lambda.instance?(*args)
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
# -- Callable
|
|
241
|
-
|
|
242
|
-
def self.Callable(object = Undefined, options = Empty::HASH)
|
|
243
|
-
default = options[:or]
|
|
244
|
-
|
|
245
|
-
return Kind::Of::Callable if Undefined == object && default.nil?
|
|
246
|
-
|
|
247
|
-
callable = object || default
|
|
248
|
-
|
|
249
|
-
return callable if callable.respond_to?(:call)
|
|
250
|
-
|
|
251
|
-
raise Kind::Error.new('Callable'.freeze, callable)
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
const_set(:Callable, ::Module.new do
|
|
255
|
-
extend Checker::Protocol
|
|
256
|
-
|
|
257
|
-
def self.__kind; Object; end
|
|
258
|
-
|
|
259
|
-
def self.class?(value)
|
|
260
|
-
Kind::Is::Callable(value)
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
def self.instance(value, options = Empty::HASH)
|
|
264
|
-
default = options[:or]
|
|
265
|
-
|
|
266
|
-
if ::Kind::Maybe::Value.none?(default)
|
|
267
|
-
__kind_undefined(value) { Kind::Of::Callable(value) }
|
|
268
|
-
else
|
|
269
|
-
return value if Kind::Undefined != value && instance?(value)
|
|
270
|
-
|
|
271
|
-
__kind_undefined(default) { Kind::Of::Callable(default) }
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
def self.__kind_undefined(value)
|
|
276
|
-
if Kind::Undefined == value
|
|
277
|
-
raise Kind::Error.new('Callable'.freeze, Kind::Undefined)
|
|
278
|
-
else
|
|
279
|
-
yield
|
|
280
|
-
end
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
def self.__is_instance__(value);
|
|
284
|
-
value.respond_to?(:call)
|
|
285
|
-
end
|
|
286
|
-
end)
|
|
287
|
-
|
|
288
|
-
def self.Callable?(*args)
|
|
289
|
-
Kind::Of::Callable.instance?(*args)
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
# ---------------------- #
|
|
293
|
-
# Built-in type checkers #
|
|
294
|
-
# ---------------------- #
|
|
295
|
-
|
|
296
|
-
# -- Classes
|
|
297
|
-
[
|
|
298
|
-
String, Symbol, Numeric, Integer, Float, Regexp, Time,
|
|
299
|
-
Array, Range, Hash, Struct, Enumerator, Set, OpenStruct,
|
|
300
|
-
Method, Proc,
|
|
301
|
-
IO, File
|
|
302
|
-
].each { |klass| Types.add(klass) }
|
|
303
|
-
|
|
304
|
-
Types.add(Queue, name: 'Queue'.freeze)
|
|
305
|
-
|
|
306
|
-
# -- Modules
|
|
307
|
-
[
|
|
308
|
-
Enumerable, Comparable
|
|
309
|
-
].each { |klass| Types.add(klass) }
|
|
310
|
-
|
|
311
|
-
# -- Kind::Of::Maybe
|
|
312
|
-
|
|
313
|
-
Types.add(Kind::Maybe::Result, name: 'Maybe'.freeze)
|
|
314
|
-
Types.add(Kind::Maybe::Result, name: 'Optional'.freeze)
|
|
315
|
-
end
|
|
316
|
-
end
|
|
3
|
+
require 'kind/basic'
|
|
4
|
+
require 'kind/objects'
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'kind/__lib__/kind'
|
|
4
|
+
require 'kind/__lib__/undefined'
|
|
5
|
+
|
|
6
|
+
module Kind
|
|
7
|
+
module ATTRIBUTES
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
def name!(name)
|
|
11
|
+
KIND.of!(::Symbol, name)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def value(kind, default, visibility = :private)
|
|
15
|
+
[kind, default, visibility]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def value_to_assign(kind, default, hash, name)
|
|
19
|
+
raw_value = hash[name]
|
|
20
|
+
|
|
21
|
+
return raw_value if kind.nil? && UNDEFINED == default
|
|
22
|
+
|
|
23
|
+
value = resolve_value_to_assign(kind, default, raw_value)
|
|
24
|
+
|
|
25
|
+
(kind.nil? || kind === value) ? value : nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def value!(kind, default)
|
|
29
|
+
return value(kind, default) unless kind.nil?
|
|
30
|
+
|
|
31
|
+
raise Error.new("kind expected to not be nil")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def value_to_assign!(kind, default, hash, name)
|
|
35
|
+
value = resolve_value_to_assign(kind, default, hash[name])
|
|
36
|
+
|
|
37
|
+
Kind.of(kind, value, label: name)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def resolve_value_to_assign(kind, default, value)
|
|
43
|
+
if kind == ::Proc
|
|
44
|
+
UNDEFINED == default ? value : KIND.value(kind, value, default)
|
|
45
|
+
else
|
|
46
|
+
default_is_a_callable = default.respond_to?(:call)
|
|
47
|
+
|
|
48
|
+
default_value =
|
|
49
|
+
if default_is_a_callable
|
|
50
|
+
default_fn = Proc === default ? default : default.method(:call)
|
|
51
|
+
|
|
52
|
+
default_fn.arity != 0 ? default_fn.call(value) : default_fn.call
|
|
53
|
+
else
|
|
54
|
+
default
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
return value if UNDEFINED == default_value
|
|
58
|
+
return default_value || value if kind.nil?
|
|
59
|
+
|
|
60
|
+
default_is_a_callable ? KIND.value(kind, default_value, value) : KIND.value(kind, value, default_value)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private_constant :ATTRIBUTES
|
|
66
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Kind
|
|
4
|
+
module KIND
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
def null?(value) # :nodoc:
|
|
8
|
+
value.nil? || Undefined == value
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def of?(kind, values) # :nodoc:
|
|
12
|
+
of_kind = -> value { kind === value }
|
|
13
|
+
|
|
14
|
+
values.empty? ? of_kind : values.all?(&of_kind)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def of!(kind, value, kind_name = nil) # :nodoc:
|
|
18
|
+
return value if kind === value
|
|
19
|
+
|
|
20
|
+
error!(kind_name || kind.name, value)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def error!(kind_name, value, label = nil) # :nodoc:
|
|
24
|
+
raise Error.new(kind_name, value, label: label)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def of_class?(value) # :nodoc:
|
|
28
|
+
value.kind_of?(::Class)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def of_module?(value) # :nodoc:
|
|
32
|
+
::Module == value || (value.kind_of?(::Module) && !of_class?(value))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def of_module_or_class!(value) # :nodoc:
|
|
36
|
+
of!(::Module, value, 'Module/Class')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def respond_to!(method_name, value) # :nodoc:
|
|
40
|
+
return value if value.respond_to?(method_name)
|
|
41
|
+
|
|
42
|
+
raise Error.new("expected #{value} to respond to :#{method_name}")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def interface?(method_names, value) # :nodoc:
|
|
46
|
+
method_names.all? { |method_name| value.respond_to?(method_name) }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def value(kind, arg, default) # :nodoc:
|
|
50
|
+
kind === arg ? arg : default
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def is?(expected, value) # :nodoc:
|
|
54
|
+
is(of_module_or_class!(expected), value)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def is(expected_kind, value) # :nodoc:
|
|
60
|
+
kind = of_module_or_class!(value)
|
|
61
|
+
|
|
62
|
+
if of_class?(kind)
|
|
63
|
+
kind <= expected_kind || expected_kind == ::Class
|
|
64
|
+
else
|
|
65
|
+
kind == expected_kind || kind.kind_of?(expected_kind)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private_constant :KIND
|
|
71
|
+
end
|