kind 2.0.0 → 2.1.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/README.md +178 -55
- data/lib/kind.rb +28 -2
- data/lib/kind/checker.rb +24 -16
- data/lib/kind/maybe.rb +28 -3
- data/lib/kind/types.rb +12 -1
- data/lib/kind/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a83d36b4c1fe131567251f418b775a8366ecf2a7c0d31682f801866cb9d83a27
|
4
|
+
data.tar.gz: b9b613500675aa1ea9e10c4b5ff83a451f289aec39896aaed025c196f0212ece
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 252e2e4f3bd9bbd09ff182579d450de170688ada607dfaa30cd70748c1ac4473381c856ba1be37f74ccd1eb05d077763cbf853ea1f356c58226408108e69f4e8
|
7
|
+
data.tar.gz: f35a606761e6de74f81427a4431c711252303f78e4b0b5d11dd5e1878180112c1733fa4fef85949f3414196e387b54c672e768384f92aff9ac1c434662529834
|
data/README.md
CHANGED
@@ -18,11 +18,14 @@ One of the goals of this project is to do simple type checking like `"some strin
|
|
18
18
|
- [Required Ruby version](#required-ruby-version)
|
19
19
|
- [Installation](#installation)
|
20
20
|
- [Usage](#usage)
|
21
|
-
- [Verifying the kind of some object](#verifying-the-kind-of-some-object)
|
22
|
-
|
21
|
+
- [Kind.of.\<Type\>() - Verifying the kind of some object](#kindoftype---verifying-the-kind-of-some-object)
|
22
|
+
- [Method aliases to perform a strict validation](#method-aliases-to-perform-a-strict-validation)
|
23
|
+
- [Kind.of.\<Type\>.or_nil()](#kindoftypeor_nil)
|
24
|
+
- [Kind.of.\<Type\>.instance?()](#kindoftypeinstance)
|
25
|
+
- [Kind.is.\<Type\>() - Verifying if some class/module is the expected kind.](#kindistype---verifying-if-some-classmodule-is-the-expected-kind)
|
23
26
|
- [How to create a new type checker?](#how-to-create-a-new-type-checker)
|
24
27
|
- [Creating/Verifiyng type checkers dynamically](#creatingverifiyng-type-checkers-dynamically)
|
25
|
-
- [Registering new (custom) type
|
28
|
+
- [Registering new (custom) type checker](#registering-new-custom-type-checker)
|
26
29
|
- [What happens if a custom type checker has a namespace?](#what-happens-if-a-custom-type-checker-has-a-namespace)
|
27
30
|
- [Type checkers](#type-checkers)
|
28
31
|
- [Classes' type checkers](#classes-type-checkers)
|
@@ -31,11 +34,15 @@ One of the goals of this project is to do simple type checking like `"some strin
|
|
31
34
|
- [Kind::Undefined](#kindundefined)
|
32
35
|
- [Kind.of.\<Type\>.or_undefined()](#kindoftypeor_undefined)
|
33
36
|
- [Kind::Maybe](#kindmaybe)
|
34
|
-
|
35
|
-
- [Kind::Maybe#
|
37
|
+
- [Replacing blocks by lambdas](#replacing-blocks-by-lambdas)
|
38
|
+
- [Kind::Maybe[] and Kind::Maybe#then method aliases](#kindmaybe-and-kindmaybethen-method-aliases)
|
39
|
+
- [Replacing blocks by lambdas](#replacing-blocks-by-lambdas-1)
|
40
|
+
- [Kind::None() and Kind::Some()](#kindnone-and-kindsome)
|
36
41
|
- [Kind.of.Maybe()](#kindofmaybe)
|
37
42
|
- [Kind::Optional](#kindoptional)
|
43
|
+
- [Replacing blocks by lambdas](#replacing-blocks-by-lambdas-2)
|
38
44
|
- [Kind.of.\<Type\>.as_optional](#kindoftypeas_optional)
|
45
|
+
- [Kind::Maybe#try](#kindmaybetry)
|
39
46
|
- [Kind::Validator (ActiveModel::Validations)](#kindvalidator-activemodelvalidations)
|
40
47
|
- [Usage](#usage-1)
|
41
48
|
- [Defining the default validation strategy](#defining-the-default-validation-strategy)
|
@@ -82,14 +89,14 @@ sum(1, 1) # 2
|
|
82
89
|
sum('1', 1) # Kind::Error ("\"1\" expected to be a kind of Numeric")
|
83
90
|
```
|
84
91
|
|
85
|
-
### Verifying the kind of some object
|
92
|
+
### Kind.of.\<Type\>() - Verifying the kind of some object
|
86
93
|
|
87
94
|
By default, basic verifications are strict. So, when you perform `Kind.of.Hash(value)`, if the given value was a Hash, the value itself will be returned, but if it isn't the right type, an error will be raised.
|
88
95
|
|
89
96
|
```ruby
|
90
|
-
Kind.of.Hash(nil)
|
91
|
-
Kind.of.Hash('')
|
92
|
-
Kind.of.Hash(
|
97
|
+
Kind.of.Hash(nil) # **raise Kind::Error, "nil expected to be a kind of Hash"**
|
98
|
+
Kind.of.Hash('') # raise Kind::Error, "'' expected to be a kind of Hash"
|
99
|
+
Kind.of.Hash(a: 1) # {a: 1}
|
93
100
|
|
94
101
|
# ---
|
95
102
|
|
@@ -99,14 +106,12 @@ Kind.of.Boolean(false) # false
|
|
99
106
|
```
|
100
107
|
|
101
108
|
> **Note:** `Kind.of.<Type>` supports the to_proc protocol.
|
102
|
-
>
|
103
|
-
> when the value has the desired kind and false if it hasn't.
|
109
|
+
> And it will perform a strict validation as expected.
|
104
110
|
|
105
111
|
```ruby
|
106
112
|
collection = [ {number: 1}, 'number 2', {number: 3}, :number_4 ]
|
107
113
|
|
108
|
-
collection
|
109
|
-
.select(&Kind.of.Hash) # [{number: 1}, {number: 3}]
|
114
|
+
collection.map(&Kind.of.Hash) # Kind::Error ("number 2" expected to be a kind of Hash)
|
110
115
|
```
|
111
116
|
|
112
117
|
When the verified value is nil, it is possible to define a default value with the same type to be returned.
|
@@ -123,6 +128,24 @@ Kind.of.Boolean(nil, or: true) # true
|
|
123
128
|
|
124
129
|
> **Note:** As an alternative syntax, you can use the `Kind::Of` instead of the `Kind.of` method. e.g: `Kind::Of::Hash('')`
|
125
130
|
|
131
|
+
#### Method aliases to perform a strict validation
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
Kind.of.Hash[nil] # raise Kind::Error, "nil expected to be a kind of Hash"
|
135
|
+
Kind.of.Hash[''] # raise Kind::Error, "'' expected to be a kind of Hash"
|
136
|
+
Kind.of.Hash[a: 1] # {a: 1}
|
137
|
+
Kind.of.Hash['', or: {}] # {}
|
138
|
+
|
139
|
+
# or
|
140
|
+
|
141
|
+
Kind.of.Hash.instance(nil) # raise Kind::Error, "nil expected to be a kind of Hash"
|
142
|
+
Kind.of.Hash.instance('') # raise Kind::Error, "'' expected to be a kind of Hash"
|
143
|
+
Kind.of.Hash.instance(a: 1) # {a: 1}
|
144
|
+
Kind.of.Hash.instance('', or: {}) # {}
|
145
|
+
```
|
146
|
+
|
147
|
+
### Kind.of.\<Type\>.or_nil()
|
148
|
+
|
126
149
|
But if you don't need a strict type verification, use the `.or_nil` method.
|
127
150
|
|
128
151
|
```ruby
|
@@ -135,11 +158,12 @@ Kind.of.Boolean.or_nil('') # nil
|
|
135
158
|
Kind.of.Boolean.or_nil(true) # true
|
136
159
|
```
|
137
160
|
|
138
|
-
|
161
|
+
### Kind.of.\<Type\>.instance?()
|
162
|
+
|
163
|
+
Use the method `.instance?` to verify if the given object has the expected type.
|
139
164
|
|
140
165
|
```ruby
|
141
|
-
Kind.of.Hash.instance?('')
|
142
|
-
# false
|
166
|
+
Kind.of.Hash.instance?('') # false
|
143
167
|
|
144
168
|
# ---
|
145
169
|
|
@@ -155,27 +179,19 @@ Kind.of.Boolean.instance?(false) # true
|
|
155
179
|
collection = [ {number: 1}, 'number 2', {number: 3}, :number_4 ]
|
156
180
|
|
157
181
|
collection
|
158
|
-
.select(&Kind.of.Hash.instance?)
|
159
|
-
.reduce(0) { |total, item| total + item.fetch(:number, 0) } # 4
|
182
|
+
.select(&Kind.of.Hash.instance?) # [{:number=>1}, {:number=>3}]
|
160
183
|
```
|
161
184
|
|
162
|
-
|
185
|
+
> **Note:** You can use a different syntax to perform an instance verification.
|
186
|
+
> To do this, use Kind.of.\<Type\>?()
|
163
187
|
|
164
188
|
```ruby
|
165
|
-
|
166
|
-
Kind.of.Hash[''] # raise Kind::Error, "'' expected to be a kind of Hash"
|
167
|
-
Kind.of.Hash[a: 1] # {a: 1}
|
168
|
-
Kind.of.Hash['', or: {}] # {}
|
169
|
-
|
170
|
-
# or
|
189
|
+
collection = [ {number: 1}, 'number 2', {number: 3}, :number_4 ]
|
171
190
|
|
172
|
-
Kind.of.Hash
|
173
|
-
Kind.of.Hash.instance('') # raise Kind::Error, "'' expected to be a kind of Hash"
|
174
|
-
Kind.of.Hash.instance(a: 1) # {a: 1}
|
175
|
-
Kind.of.Hash.instance('', or: {}) # {}
|
191
|
+
collection.select(&Kind.of.Hash?) # [{:number=>1}, {:number=>3}]
|
176
192
|
```
|
177
193
|
|
178
|
-
###
|
194
|
+
### Kind.is.\<Type\>() - Verifying if some class/module is the expected kind.
|
179
195
|
|
180
196
|
You can use `Kind.is` to verify if some class has the expected type as its ancestor.
|
181
197
|
|
@@ -262,6 +278,22 @@ Kind.of(User, {}) # Kind::Error ({} expected to be a kind of User)
|
|
262
278
|
Kind.of(Hash, {}) # {}
|
263
279
|
Kind.of(Hash, user) # Kind::Error (<User ...> expected to be a kind of Hash)
|
264
280
|
|
281
|
+
# ----------------------------------------- #
|
282
|
+
# Verifiyng if the value is a kind instance #
|
283
|
+
# ----------------------------------------- #
|
284
|
+
|
285
|
+
Kind.of?(Numeric, 1) # true
|
286
|
+
Kind.of?(Numeric, 1, 2.0) # true
|
287
|
+
|
288
|
+
Kind.of?(Numeric, '1') # false
|
289
|
+
Kind.of?(Numeric, 1, '2.0') # false
|
290
|
+
|
291
|
+
# Note: Kind.of?(Type) without arguments will return a
|
292
|
+
# lambda that will perform an instance verification
|
293
|
+
#
|
294
|
+
[1, '2', 3.0, '4']
|
295
|
+
.select(&Kind.of?(Numeric)) # [1, 3.0]
|
296
|
+
|
265
297
|
# ---------------------------------- #
|
266
298
|
# Creating type checkers dynamically #
|
267
299
|
# ---------------------------------- #
|
@@ -300,7 +332,7 @@ end
|
|
300
332
|
Kind.is(User, AdminUser) # true
|
301
333
|
```
|
302
334
|
|
303
|
-
#### Registering new (custom) type
|
335
|
+
#### Registering new (custom) type checker
|
304
336
|
|
305
337
|
Use `Kind::Types.add()`. e.g:
|
306
338
|
|
@@ -491,7 +523,27 @@ puts optional.value_or(1) # 1
|
|
491
523
|
puts optional.value_or { 1 } # 1
|
492
524
|
```
|
493
525
|
|
494
|
-
|
526
|
+
#### Replacing blocks by lambdas
|
527
|
+
|
528
|
+
```ruby
|
529
|
+
Add = -> params do
|
530
|
+
a, b = Kind.of.Hash(params, or: Empty::HASH).values_at(:a, :b)
|
531
|
+
|
532
|
+
a + b if Kind.of.Numeric?(a, b)
|
533
|
+
end
|
534
|
+
|
535
|
+
# --
|
536
|
+
|
537
|
+
Kind::Maybe.new(a: 1, b: 2).map(&Add).value_or(0) # 3
|
538
|
+
|
539
|
+
# --
|
540
|
+
|
541
|
+
Kind::Maybe.new([]).map(&Add).value_or(0) # 0
|
542
|
+
Kind::Maybe.new({}).map(&Add).value_or(0) # 0
|
543
|
+
Kind::Maybe.new(nil).map(&Add).value_or(0) # 0
|
544
|
+
```
|
545
|
+
|
546
|
+
### Kind::Maybe[] and Kind::Maybe#then method aliases
|
495
547
|
|
496
548
|
You can use `Kind::Maybe[]` (brackets) instead of the `.new` to transform values in a `Kind::Maybe`. Another alias is `.then` to the `.map` method.
|
497
549
|
|
@@ -505,43 +557,57 @@ result =
|
|
505
557
|
puts result # 42
|
506
558
|
```
|
507
559
|
|
508
|
-
|
509
|
-
|
510
|
-
If you don't want to use a map to access the value, you could use the `#try` method to access it. So, if the value wasn't `nil` or `Kind::Undefined`, it will be returned.
|
560
|
+
#### Replacing blocks by lambdas
|
511
561
|
|
512
562
|
```ruby
|
513
|
-
|
563
|
+
Add = -> params do
|
564
|
+
a, b = Kind.of.Hash(params, or: Empty::HASH).values_at(:a, :b)
|
514
565
|
|
515
|
-
|
566
|
+
a + b if Kind.of.Numeric.instance?(a, b)
|
567
|
+
end
|
516
568
|
|
517
|
-
|
569
|
+
# --
|
518
570
|
|
519
|
-
|
571
|
+
Kind::Maybe[a: 1, b: 2].then(&Add).value_or(0) # 3
|
520
572
|
|
521
|
-
|
573
|
+
# --
|
522
574
|
|
523
|
-
|
524
|
-
#
|
525
|
-
|
575
|
+
Kind::Maybe[1].then(&Add).value_or(0) # 0
|
576
|
+
Kind::Maybe['2'].then(&Add).value_or(0) # 0
|
577
|
+
Kind::Maybe[nil].then(&Add).value_or(0) # 0
|
578
|
+
```
|
526
579
|
|
527
|
-
|
580
|
+
### Kind::None() and Kind::Some()
|
528
581
|
|
529
|
-
|
582
|
+
If you need to ensure the return of `Kind::Maybe` results from your methods/lambdas,
|
583
|
+
you could use the methods `Kind::None` and `Kind::Some` to do this. e.g:
|
530
584
|
|
531
|
-
|
585
|
+
```ruby
|
586
|
+
Add = -> params do
|
587
|
+
a, b = Kind.of.Hash(params, or: Empty::HASH).values_at(:a, :b)
|
532
588
|
|
533
|
-
|
534
|
-
# Kind::Undefined value #
|
535
|
-
#########################
|
589
|
+
return Kind::None unless Kind.of.Numeric.instance?(a, b)
|
536
590
|
|
537
|
-
|
591
|
+
Kind::Some(a + b)
|
592
|
+
end
|
538
593
|
|
539
|
-
|
594
|
+
# --
|
540
595
|
|
541
|
-
|
542
|
-
|
596
|
+
Add.call(1) # #<Kind::Maybe::None:0x0000... @value=nil>
|
597
|
+
Add.call({}) # #<Kind::Maybe::None:0x0000... @value=nil>
|
598
|
+
Add.call(a: 1) # #<Kind::Maybe::None:0x0000... @value=nil>
|
599
|
+
Add.call(b: 2) # #<Kind::Maybe::None:0x0000... @value=nil>
|
543
600
|
|
544
|
-
|
601
|
+
Add.call(a:1, b: 2) # #<Kind::Maybe::Some:0x0000... @value=3>
|
602
|
+
|
603
|
+
# --
|
604
|
+
|
605
|
+
Kind::Maybe[a: 1, b: 2].then(&Add).value_or(0) # 3
|
606
|
+
|
607
|
+
Kind::Maybe[1].then(&Add).value_or(0) # 0
|
608
|
+
Kind::Maybe['2'].then(&Add).value_or(0) # 0
|
609
|
+
Kind::Maybe[nil].then(&Add).value_or(0) # 0
|
610
|
+
```
|
545
611
|
|
546
612
|
### Kind.of.Maybe()
|
547
613
|
|
@@ -598,6 +664,26 @@ result2 =
|
|
598
664
|
puts result2 # 35
|
599
665
|
```
|
600
666
|
|
667
|
+
#### Replacing blocks by lambdas
|
668
|
+
|
669
|
+
```ruby
|
670
|
+
Add = -> params do
|
671
|
+
a, b = Kind.of.Hash(params, or: Empty::HASH).values_at(:a, :b)
|
672
|
+
|
673
|
+
a + b if Kind.of.Numeric.instance?(a, b)
|
674
|
+
end
|
675
|
+
|
676
|
+
# --
|
677
|
+
|
678
|
+
Kind::Optional[a: 1, b: 2].then(&Add).value_or(0) # 3
|
679
|
+
|
680
|
+
# --
|
681
|
+
|
682
|
+
Kind::Optional[1].then(&Add).value_or(0) # 0
|
683
|
+
Kind::Optional['2'].then(&Add).value_or(0) # 0
|
684
|
+
Kind::Optional[nil].then(&Add).value_or(0) # 0
|
685
|
+
```
|
686
|
+
|
601
687
|
**Note:** The `Kind.of.Optional` is available to check if some value is a `Kind::Optional`.
|
602
688
|
|
603
689
|
[⬆️ Back to Top](#table-of-contents-)
|
@@ -709,6 +795,44 @@ end
|
|
709
795
|
|
710
796
|
[⬆️ Back to Top](#table-of-contents-)
|
711
797
|
|
798
|
+
### Kind::Maybe#try
|
799
|
+
|
800
|
+
If you don't want to use a map to access the value, you could use the `#try` method to access it. So, if the value wasn't `nil` or `Kind::Undefined`, it will be returned.
|
801
|
+
|
802
|
+
```ruby
|
803
|
+
object = 'foo'
|
804
|
+
|
805
|
+
p Kind::Maybe[object].try(:upcase) # "FOO"
|
806
|
+
|
807
|
+
p Kind::Maybe[{}].try(:fetch, :number, 0) # 0
|
808
|
+
|
809
|
+
p Kind::Maybe[{number: 1}].try(:fetch, :number) # 1
|
810
|
+
|
811
|
+
p Kind::Maybe[object].try { |value| value.upcase } # "FOO"
|
812
|
+
|
813
|
+
#############
|
814
|
+
# Nil value #
|
815
|
+
#############
|
816
|
+
|
817
|
+
object = nil
|
818
|
+
|
819
|
+
p Kind::Maybe[object].try(:upcase) # nil
|
820
|
+
|
821
|
+
p Kind::Maybe[object].try { |value| value.upcase } # nil
|
822
|
+
|
823
|
+
#########################
|
824
|
+
# Kind::Undefined value #
|
825
|
+
#########################
|
826
|
+
|
827
|
+
object = Kind::Undefined
|
828
|
+
|
829
|
+
p Kind::Maybe[object].try(:upcase) # nil
|
830
|
+
|
831
|
+
p Kind::Maybe[object].try { |value| value.upcase } # nil
|
832
|
+
```
|
833
|
+
|
834
|
+
[⬆️ Back to Top](#table-of-contents-)
|
835
|
+
|
712
836
|
## Kind::Validator (ActiveModel::Validations)
|
713
837
|
|
714
838
|
This module enables the capability to validate types via [`ActiveModel::Validations >= 3.2, < 6.1.0`](https://api.rubyonrails.org/classes/ActiveModel/Validations.html). e.g
|
@@ -839,7 +963,6 @@ Kind::Validator.default_strategy = :instance_of
|
|
839
963
|
```
|
840
964
|
|
841
965
|
And these are the available options to define the default strategy:
|
842
|
-
- `is_a`
|
843
966
|
- `kind_of` *(default)*
|
844
967
|
- `instance_of`
|
845
968
|
|
data/lib/kind.rb
CHANGED
@@ -29,6 +29,12 @@ module Kind
|
|
29
29
|
|
30
30
|
private_constant :MODULE_OR_CLASS
|
31
31
|
|
32
|
+
private_class_method def self.__checkers__
|
33
|
+
@__checkers__ ||= {}
|
34
|
+
end
|
35
|
+
|
36
|
+
__checkers__
|
37
|
+
|
32
38
|
def self.of(kind = Undefined, object = Undefined)
|
33
39
|
return Of if kind == Undefined && object == Undefined
|
34
40
|
|
@@ -45,8 +51,8 @@ module Kind
|
|
45
51
|
end
|
46
52
|
end
|
47
53
|
|
48
|
-
|
49
|
-
|
54
|
+
def self.of?(kind, *args)
|
55
|
+
Kind.of(kind).instance?(*args)
|
50
56
|
end
|
51
57
|
|
52
58
|
# --------------------- #
|
@@ -90,6 +96,10 @@ module Kind
|
|
90
96
|
def self.__is_instance__(value); class?(value); end
|
91
97
|
end)
|
92
98
|
|
99
|
+
def self.Class?(*args)
|
100
|
+
Kind::Of::Class.instance?(*args)
|
101
|
+
end
|
102
|
+
|
93
103
|
# -- Module
|
94
104
|
|
95
105
|
def self.Module(object = Undefined)
|
@@ -136,6 +146,10 @@ module Kind
|
|
136
146
|
def self.__is_instance__(value); class?(value); end
|
137
147
|
end)
|
138
148
|
|
149
|
+
def self.Module?(*args)
|
150
|
+
Kind::Of::Module.instance?(*args)
|
151
|
+
end
|
152
|
+
|
139
153
|
# -- Boolean
|
140
154
|
|
141
155
|
def self.Boolean(object = Undefined, options = Empty::HASH)
|
@@ -187,6 +201,10 @@ module Kind
|
|
187
201
|
end
|
188
202
|
end)
|
189
203
|
|
204
|
+
def self.Boolean?(*args)
|
205
|
+
Kind::Of::Boolean.instance?(*args)
|
206
|
+
end
|
207
|
+
|
190
208
|
# -- Lambda
|
191
209
|
|
192
210
|
def self.Lambda(object = Undefined, options = Empty::HASH)
|
@@ -231,6 +249,10 @@ module Kind
|
|
231
249
|
end
|
232
250
|
end)
|
233
251
|
|
252
|
+
def self.Lambda?(*args)
|
253
|
+
Kind::Of::Lambda.instance?(*args)
|
254
|
+
end
|
255
|
+
|
234
256
|
# -- Callable
|
235
257
|
|
236
258
|
def self.Callable(object = Undefined, options = Empty::HASH)
|
@@ -279,6 +301,10 @@ module Kind
|
|
279
301
|
end
|
280
302
|
end)
|
281
303
|
|
304
|
+
def self.Callable?(*args)
|
305
|
+
Kind::Of::Callable.instance?(*args)
|
306
|
+
end
|
307
|
+
|
282
308
|
# ---------------------- #
|
283
309
|
# Built-in type checkers #
|
284
310
|
# ---------------------- #
|
data/lib/kind/checker.rb
CHANGED
@@ -18,21 +18,29 @@ module Kind
|
|
18
18
|
instance(value, options)
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
to_proc
|
21
|
+
def to_proc
|
22
|
+
@to_proc ||=
|
23
|
+
-> checker { -> value { checker.instance(value) } }.call(self)
|
25
24
|
end
|
26
25
|
|
27
26
|
def __is_instance__(value)
|
28
|
-
value.
|
27
|
+
value.kind_of?(__kind)
|
29
28
|
end
|
30
29
|
|
31
|
-
def
|
32
|
-
@
|
30
|
+
def is_instance_to_proc
|
31
|
+
@is_instance_to_proc ||=
|
33
32
|
-> checker { -> value { checker.__is_instance__(value) } }.call(self)
|
34
33
|
end
|
35
34
|
|
35
|
+
def instance?(*args)
|
36
|
+
return is_instance_to_proc if args.empty?
|
37
|
+
|
38
|
+
return args.all? { |object| __is_instance__(object) } if args.size > 1
|
39
|
+
|
40
|
+
arg = args[0]
|
41
|
+
arg == Kind::Undefined ? is_instance_to_proc : __is_instance__(arg)
|
42
|
+
end
|
43
|
+
|
36
44
|
def or_nil(value)
|
37
45
|
return value if instance?(value)
|
38
46
|
end
|
@@ -41,6 +49,15 @@ module Kind
|
|
41
49
|
or_nil(value) || Kind::Undefined
|
42
50
|
end
|
43
51
|
|
52
|
+
def __as_maybe__(value)
|
53
|
+
Kind::Maybe.new(or_nil(value))
|
54
|
+
end
|
55
|
+
|
56
|
+
def as_maybe_to_proc
|
57
|
+
@as_maybe_to_proc ||=
|
58
|
+
-> checker { -> value { checker.__as_maybe__(value) } }.call(self)
|
59
|
+
end
|
60
|
+
|
44
61
|
def as_maybe(value = Kind::Undefined)
|
45
62
|
return __as_maybe__(value) if value != Kind::Undefined
|
46
63
|
|
@@ -50,15 +67,6 @@ module Kind
|
|
50
67
|
def as_optional(value = Kind::Undefined)
|
51
68
|
as_maybe(value)
|
52
69
|
end
|
53
|
-
|
54
|
-
def __as_maybe__(value)
|
55
|
-
Kind::Maybe.new(or_nil(value))
|
56
|
-
end
|
57
|
-
|
58
|
-
def as_maybe_to_proc
|
59
|
-
@as_maybe_to_proc ||=
|
60
|
-
-> checker { -> value { checker.__as_maybe__(value) } }.call(self)
|
61
|
-
end
|
62
70
|
end
|
63
71
|
|
64
72
|
private_constant :Checkable
|
data/lib/kind/maybe.rb
CHANGED
@@ -16,7 +16,7 @@ module Kind
|
|
16
16
|
attr_reader :value
|
17
17
|
|
18
18
|
def initialize(value)
|
19
|
-
@value = value
|
19
|
+
@value = value.kind_of?(Result) ? value.value : value
|
20
20
|
end
|
21
21
|
|
22
22
|
def value_or(method_name = Undefined, &block)
|
@@ -44,7 +44,7 @@ module Kind
|
|
44
44
|
def value_or(default = Undefined, &block)
|
45
45
|
raise ArgumentError, INVALID_DEFAULT_ARG if default == Undefined && !block
|
46
46
|
|
47
|
-
|
47
|
+
default != Undefined ? default : block.call
|
48
48
|
end
|
49
49
|
|
50
50
|
def none?; true; end
|
@@ -79,6 +79,7 @@ module Kind
|
|
79
79
|
def map(&fn)
|
80
80
|
result = fn.call(@value)
|
81
81
|
|
82
|
+
return result if Maybe::None === result
|
82
83
|
return NONE_WITH_NIL_VALUE if result == nil
|
83
84
|
return NONE_WITH_UNDEFINED_VALUE if result == Undefined
|
84
85
|
|
@@ -98,13 +99,37 @@ module Kind
|
|
98
99
|
|
99
100
|
def self.new(value)
|
100
101
|
result_type = Maybe::Value.none?(value) ? None : Some
|
101
|
-
result_type.new(value
|
102
|
+
result_type.new(value)
|
102
103
|
end
|
103
104
|
|
104
105
|
def self.[](value);
|
105
106
|
new(value)
|
106
107
|
end
|
108
|
+
|
109
|
+
def self.none
|
110
|
+
NONE_WITH_NIL_VALUE
|
111
|
+
end
|
112
|
+
|
113
|
+
VALUE_CANT_BE_NONE = "value can't be nil or Kind::Undefined".freeze
|
114
|
+
|
115
|
+
private_constant :VALUE_CANT_BE_NONE
|
116
|
+
|
117
|
+
def self.some(value)
|
118
|
+
return Maybe::Some.new(value) if Value.some?(value)
|
119
|
+
|
120
|
+
raise ArgumentError, VALUE_CANT_BE_NONE
|
121
|
+
end
|
107
122
|
end
|
108
123
|
|
109
124
|
Optional = Maybe
|
125
|
+
|
126
|
+
None = Maybe.none
|
127
|
+
|
128
|
+
def self.None
|
129
|
+
Kind::None
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.Some(value)
|
133
|
+
Maybe.some(value)
|
134
|
+
end
|
110
135
|
end
|
data/lib/kind/types.rb
CHANGED
@@ -12,7 +12,17 @@ module Kind
|
|
12
12
|
|
13
13
|
return Kind::Of::%{kind_name} if object == Undefined && default.nil?
|
14
14
|
|
15
|
-
Kind::Of
|
15
|
+
is_instance = Kind::Of::%{kind_name}.__is_instance__(object)
|
16
|
+
|
17
|
+
return object if is_instance
|
18
|
+
|
19
|
+
Kind::Of.(::%{kind_name_to_check}, object && default ? default : object || default)
|
20
|
+
end
|
21
|
+
RUBY
|
22
|
+
|
23
|
+
KIND_OF_IS = <<-RUBY
|
24
|
+
def self.%{method_name}?(*args)
|
25
|
+
Kind::Of::%{kind_name}.instance?(*args)
|
16
26
|
end
|
17
27
|
RUBY
|
18
28
|
|
@@ -93,6 +103,7 @@ module Kind
|
|
93
103
|
|
94
104
|
kind_of_mod.instance_eval(KIND_OF % params)
|
95
105
|
kind_of_mod.const_set(method_name, kind_checker)
|
106
|
+
kind_of_mod.instance_eval(KIND_OF_IS % params)
|
96
107
|
end
|
97
108
|
|
98
109
|
unless kind_is_mod.respond_to?(method_name)
|
data/lib/kind/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kind
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rodrigo Serradura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A simple type system (at runtime) for Ruby - free of dependencies.
|
14
14
|
email:
|