algebrick 0.3.0 → 0.3.1
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 +3 -5
- data/VERSION +1 -1
- data/lib/algebrick.rb +92 -39
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3afd890330088870db253424a7296f619666dbe5
|
4
|
+
data.tar.gz: 6660ee990c34420c9599f5cb2f43a80c1d33ae4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d737796cb0b2ece44f606cf2d5cc9c6273893b23de0c355ebb290f09e6e35e997d33af220298bded254281ffe71cfed4abd5680c3646a004f385c7240b306980
|
7
|
+
data.tar.gz: baeb8506f6f66ee19891b1f2921b8fe45e4aa5efeecb22b2e2b3b6c23ad4e421ebad7f7c2c035d88b6563028adadcd7b9805d67c2a9b8ae72715b0e6afb70f96
|
data/README.md
CHANGED
@@ -20,11 +20,9 @@ Let's define a Tree
|
|
20
20
|
|
21
21
|
```ruby
|
22
22
|
Tree = Algebrick.type do |tree|
|
23
|
-
Empty =
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
variants Empty, Leaf, Node
|
23
|
+
variants Empty = atom,
|
24
|
+
Leaf = type { fields Integer },
|
25
|
+
Node = type { fields tree, tree }
|
28
26
|
end
|
29
27
|
```
|
30
28
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
data/lib/algebrick.rb
CHANGED
@@ -18,6 +18,8 @@
|
|
18
18
|
# TODO add method matcher (:size, matcher)
|
19
19
|
# TODO Menu modeling example, add TypedArray
|
20
20
|
# TODO update actor pattern example when gem is done
|
21
|
+
# TODO gemmify reclude
|
22
|
+
# TODO gemmify typecheck
|
21
23
|
|
22
24
|
require 'monitor'
|
23
25
|
|
@@ -32,40 +34,90 @@ module Algebrick
|
|
32
34
|
@version ||= Gem::Version.new File.read(File.join(File.dirname(__FILE__), '..', 'VERSION'))
|
33
35
|
end
|
34
36
|
|
37
|
+
# fix module to re-include itself to where it was already included when a module is included into it
|
38
|
+
module Reclude
|
39
|
+
def included(base)
|
40
|
+
included_into << base
|
41
|
+
super base
|
42
|
+
end
|
43
|
+
|
44
|
+
def include(*modules)
|
45
|
+
super(*modules)
|
46
|
+
modules.reverse.each do |module_being_included|
|
47
|
+
included_into.each do |mod|
|
48
|
+
mod.send :include, module_being_included
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def included_into
|
56
|
+
@included_into ||= []
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
35
60
|
module TypeCheck
|
36
|
-
def
|
37
|
-
|
61
|
+
def Type?(value, *types)
|
62
|
+
types.any? { |t| value.is_a? t }
|
38
63
|
end
|
39
64
|
|
40
|
-
def
|
41
|
-
|
65
|
+
def Type!(value, *types)
|
66
|
+
Type?(value, *types) or
|
67
|
+
TypeCheck.error(value, 'is not', types)
|
68
|
+
value
|
42
69
|
end
|
43
70
|
|
44
|
-
def
|
45
|
-
|
71
|
+
def Match?(value, *types)
|
72
|
+
types.any? { |t| t === value }
|
46
73
|
end
|
47
74
|
|
48
|
-
def
|
49
|
-
|
75
|
+
def Match!(value, *types)
|
76
|
+
Match?(value, *types) or
|
77
|
+
TypeCheck.error(value, 'is not matching', types)
|
78
|
+
value
|
79
|
+
end
|
80
|
+
|
81
|
+
def Child?(value, *types)
|
82
|
+
Type?(value, Class) &&
|
83
|
+
types.any? { |t| value <= t }
|
84
|
+
end
|
85
|
+
|
86
|
+
def Child!(value, *types)
|
87
|
+
Child?(value, *types) or
|
88
|
+
TypeCheck.error(value, 'is not child', types)
|
89
|
+
value
|
50
90
|
end
|
51
91
|
|
52
92
|
private
|
53
93
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
94
|
+
def self.error(value, message, types)
|
95
|
+
raise TypeError,
|
96
|
+
"value (#{value.class}) '#{value}' #{message} any of #{types.join(', ')}"
|
97
|
+
end
|
98
|
+
|
99
|
+
public
|
100
|
+
|
101
|
+
raise 'remove deprecations' if Algebrick.version >= Gem::Version.new('0.4')
|
102
|
+
|
103
|
+
def is_kind_of?(value, *types)
|
104
|
+
warn "is_kind_of? is deprecated use Type?\n#{caller[0]}"
|
105
|
+
Type? value, *types
|
106
|
+
end
|
107
|
+
|
108
|
+
def is_kind_of!(value, *types)
|
109
|
+
warn "Type! is deprecated use Type!\n#{caller[0]}"
|
110
|
+
Type! value, *types
|
111
|
+
end
|
112
|
+
|
113
|
+
def is_matching?(value, *types)
|
114
|
+
warn "is_matching? is deprecated use Match?\n#{caller[0]}"
|
115
|
+
Match? value, *types
|
116
|
+
end
|
117
|
+
|
118
|
+
def is_matching!(value, *types)
|
119
|
+
warn "is_matching! is deprecated use Match!\n#{caller[0]}"
|
120
|
+
Match! value, *types
|
69
121
|
end
|
70
122
|
end
|
71
123
|
|
@@ -90,6 +142,8 @@ module Algebrick
|
|
90
142
|
raise "no match for (#{value.class}) '#{value}' by any of #{cases.map(&:first).join ', '}"
|
91
143
|
end
|
92
144
|
|
145
|
+
# TODO #match! raise when match is not complete on a given type
|
146
|
+
|
93
147
|
private
|
94
148
|
|
95
149
|
def self.match_value(matcher, block)
|
@@ -147,6 +201,7 @@ module Algebrick
|
|
147
201
|
include TypeCheck
|
148
202
|
include Matching
|
149
203
|
include MatcherDelegations
|
204
|
+
include Reclude
|
150
205
|
|
151
206
|
def initialize(name, &definition)
|
152
207
|
super &definition
|
@@ -258,9 +313,7 @@ module Algebrick
|
|
258
313
|
if fields.size == 1 && fields.first.is_a?(Hash)
|
259
314
|
fields = type.field_names.map { |k| fields.first[k] }
|
260
315
|
end
|
261
|
-
@fields = fields.zip(self.class.type.fields).map
|
262
|
-
is_kind_of! field, type
|
263
|
-
end.freeze
|
316
|
+
@fields = fields.zip(self.class.type.fields).map { |field, type| Type! field, type }.freeze
|
264
317
|
end
|
265
318
|
|
266
319
|
def to_s
|
@@ -336,9 +389,9 @@ module Algebrick
|
|
336
389
|
raise ArgumentError
|
337
390
|
end
|
338
391
|
|
339
|
-
|
392
|
+
add_field_names keys if keys
|
340
393
|
|
341
|
-
fields.all? { |f|
|
394
|
+
fields.all? { |f| Type! f, Type, Class, Module }
|
342
395
|
raise TypeError, 'there is no product with zero fields' unless fields.size > 0
|
343
396
|
define_method(:value) { @fields.first } if fields.size == 1
|
344
397
|
@fields = fields
|
@@ -378,7 +431,7 @@ module Algebrick
|
|
378
431
|
|
379
432
|
def set_variants(variants)
|
380
433
|
raise TypeError, 'can be set only once' if @variants
|
381
|
-
variants.all? { |v|
|
434
|
+
variants.all? { |v| Type! v, Type, Class }
|
382
435
|
@variants = variants
|
383
436
|
apply_be_kind_of
|
384
437
|
variants.each do |v|
|
@@ -500,9 +553,9 @@ module Algebrick
|
|
500
553
|
"#{name}(#{fields_str.join ', '})"
|
501
554
|
end
|
502
555
|
|
503
|
-
def
|
556
|
+
def add_field_names(names)
|
504
557
|
@field_names = names
|
505
|
-
names.all? { |k|
|
558
|
+
names.all? { |k| Type! k, Symbol }
|
506
559
|
dict = @field_indexes =
|
507
560
|
Hash.new { |h, k| raise ArgumentError, "unknown field #{k.inspect} in #{self}" }.
|
508
561
|
update names.each_with_index.inject({}) { |h, (k, i)| h.update k => i }
|
@@ -516,7 +569,7 @@ module Algebrick
|
|
516
569
|
|
517
570
|
fields = hash[FIELDS_KEY] || hash[FIELDS_KEY.to_s] ||
|
518
571
|
hash.reject { |k, _| k.to_s == TYPE_KEY.to_s }
|
519
|
-
|
572
|
+
Type! fields, Hash, Array
|
520
573
|
|
521
574
|
case fields
|
522
575
|
when Array
|
@@ -555,7 +608,7 @@ module Algebrick
|
|
555
608
|
attr_reader :variables, :fields, :variants
|
556
609
|
|
557
610
|
def initialize(variables)
|
558
|
-
@variables = variables.each { |v|
|
611
|
+
@variables = variables.each { |v| Type! v, Symbol }
|
559
612
|
@fields = nil
|
560
613
|
@variants = nil
|
561
614
|
@cache = {}
|
@@ -563,7 +616,7 @@ module Algebrick
|
|
563
616
|
end
|
564
617
|
|
565
618
|
def set_fields(fields)
|
566
|
-
@fields =
|
619
|
+
@fields = Type! fields, Hash, Array
|
567
620
|
end
|
568
621
|
|
569
622
|
def field_names
|
@@ -578,7 +631,7 @@ module Algebrick
|
|
578
631
|
end
|
579
632
|
|
580
633
|
def set_variants(variants)
|
581
|
-
@variants =
|
634
|
+
@variants = Type! variants, Array
|
582
635
|
end
|
583
636
|
|
584
637
|
def [](*assigned_types)
|
@@ -664,7 +717,7 @@ module Algebrick
|
|
664
717
|
attr_reader :new_type
|
665
718
|
|
666
719
|
def initialize(new_type, &block)
|
667
|
-
@new_type =
|
720
|
+
@new_type = Type! new_type, ProductVariant, ParametrizedType
|
668
721
|
instance_exec @new_type, &block
|
669
722
|
@new_type.kind if @new_type.is_a? ProductVariant
|
670
723
|
end
|
@@ -1039,7 +1092,7 @@ module Algebrick
|
|
1039
1092
|
|
1040
1093
|
def initialize(algebraic_type, *field_matchers)
|
1041
1094
|
super()
|
1042
|
-
@algebraic_type =
|
1095
|
+
@algebraic_type = Type! algebraic_type, Algebrick::ProductVariant, Algebrick::ParametrizedType
|
1043
1096
|
raise ArgumentError unless algebraic_type.fields
|
1044
1097
|
@field_matchers = case
|
1045
1098
|
|
@@ -1102,7 +1155,7 @@ module Algebrick
|
|
1102
1155
|
class Variant < Wrapper
|
1103
1156
|
def initialize(something)
|
1104
1157
|
raise ArgumentError unless something.variants
|
1105
|
-
|
1158
|
+
Type! something, Algebrick::ProductVariant
|
1106
1159
|
super something
|
1107
1160
|
end
|
1108
1161
|
|
@@ -1113,7 +1166,7 @@ module Algebrick
|
|
1113
1166
|
|
1114
1167
|
class Atom < Wrapper
|
1115
1168
|
def initialize(something)
|
1116
|
-
|
1169
|
+
Type! something, Algebrick::Atom
|
1117
1170
|
super something
|
1118
1171
|
end
|
1119
1172
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: algebrick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Petr Chalupa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|