moosex 0.0.18 → 0.0.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog +13 -8
- data/Gemfile.lock +1 -1
- data/README.md +180 -17
- data/lib/moosex.rb +4 -1
- data/lib/moosex/attribute.rb +94 -72
- data/lib/moosex/attribute/modifiers.rb +31 -32
- data/lib/moosex/event.rb +1 -1
- data/lib/moosex/meta.rb +12 -3
- data/lib/moosex/traits.rb +115 -0
- data/lib/moosex/types.rb +3 -3
- data/lib/moosex/version.rb +1 -1
- data/samples/events.rb +1 -1
- data/samples/point.rb +1 -1
- data/spec/baz_spec.rb +1 -1
- data/spec/coerce_spec.rb +3 -36
- data/spec/lazy_spec.rb +2 -2
- data/spec/meta_spec.rb +14 -0
- data/spec/modifiers_spec.rb +6 -6
- data/spec/parametric_role_spec.rb +2 -2
- data/spec/plugin_spec.rb +74 -0
- data/spec/point_spec.rb +1 -1
- data/spec/proxy_spec.rb +9 -9
- data/spec/traits_spec.rb +324 -0
- data/spec/trigger_spec.rb +3 -3
- data/spec/types_spec.rb +1 -1
- data/spec/weak_spec.rb +1 -1
- metadata +7 -2
@@ -1,10 +1,15 @@
|
|
1
1
|
module MooseX
|
2
|
-
|
2
|
+
module AttributeModifiers
|
3
|
+
module ThirdParty
|
4
|
+
end
|
3
5
|
module AttrBaseModifier
|
4
6
|
def process(options, attr_symbol)
|
5
7
|
@attr_symbol = attr_symbol
|
6
8
|
|
7
|
-
local_options = {
|
9
|
+
local_options = {
|
10
|
+
name => default
|
11
|
+
}.merge(options)
|
12
|
+
|
8
13
|
options.delete(name)
|
9
14
|
|
10
15
|
return nil unless local_options.has_key?(name)
|
@@ -18,6 +23,7 @@ module MooseX
|
|
18
23
|
attr
|
19
24
|
end
|
20
25
|
|
26
|
+
def name; self.class.name.downcase.split("::").last.to_sym ; end
|
21
27
|
def default; nil; end
|
22
28
|
def coerce(x,f); x ; end
|
23
29
|
def validate(x,f); end
|
@@ -40,8 +46,8 @@ module MooseX
|
|
40
46
|
def coerce(x, field_name)
|
41
47
|
unless x.is_a? Proc
|
42
48
|
x_name = x.to_sym
|
43
|
-
x =
|
44
|
-
object.
|
49
|
+
x = ->(object, *value) do
|
50
|
+
object.__send__(x_name,*value)
|
45
51
|
end
|
46
52
|
end
|
47
53
|
|
@@ -58,7 +64,6 @@ module MooseX
|
|
58
64
|
class Is
|
59
65
|
include AttrBaseModifier
|
60
66
|
include AttrCoerceToSymbol
|
61
|
-
def name; :is ; end
|
62
67
|
def default; :rw ; end
|
63
68
|
def validate(is, field_name)
|
64
69
|
unless [:rw, :rwp, :ro, :lazy, :private].include?(is)
|
@@ -81,26 +86,23 @@ module MooseX
|
|
81
86
|
|
82
87
|
class Isa
|
83
88
|
include AttrBaseModifier
|
84
|
-
def name; :isa ; end
|
85
89
|
def default; MooseX::Attribute.isAny ; end
|
86
90
|
def coerce(isa, field_name); MooseX::Attribute.isType(isa); end
|
87
91
|
end
|
88
92
|
|
89
93
|
class Default
|
90
94
|
include AttrBaseModifier
|
91
|
-
def name; :default ; end
|
92
95
|
def coerce(default, field_name)
|
93
96
|
if default.is_a?(Proc) || default.nil?
|
94
97
|
return default
|
95
98
|
end
|
96
|
-
return
|
99
|
+
return -> { default }
|
97
100
|
end
|
98
101
|
end
|
99
102
|
|
100
103
|
class Required
|
101
104
|
include AttrBaseModifier
|
102
105
|
include AttrCoerceToBoolean
|
103
|
-
def name; :required ; end
|
104
106
|
end
|
105
107
|
|
106
108
|
module AttrCoerceToMethodBasedOnFieldName
|
@@ -124,7 +126,6 @@ module MooseX
|
|
124
126
|
include AttrBaseModifier
|
125
127
|
include AttrCoerceToMethodBasedOnFieldName
|
126
128
|
|
127
|
-
def name; :predicate ; end
|
128
129
|
def method_name(field_name); "has_#{field_name}?".to_sym ; end
|
129
130
|
end
|
130
131
|
|
@@ -132,13 +133,11 @@ module MooseX
|
|
132
133
|
include AttrBaseModifier
|
133
134
|
include AttrCoerceToMethodBasedOnFieldName
|
134
135
|
|
135
|
-
def name; :clearer ; end
|
136
136
|
def method_name(field_name); "clear_#{field_name}!".to_sym ; end
|
137
137
|
end
|
138
138
|
|
139
139
|
class Handles
|
140
140
|
include AttrBaseModifier
|
141
|
-
def name; :handles ; end
|
142
141
|
def default; {} ; end
|
143
142
|
|
144
143
|
def populate_handles(handles, field_name)
|
@@ -198,13 +197,11 @@ module MooseX
|
|
198
197
|
class Lazy
|
199
198
|
include AttrBaseModifier
|
200
199
|
include AttrCoerceToBoolean
|
201
|
-
def name; :lazy ; end
|
202
200
|
end
|
203
201
|
|
204
202
|
class Reader
|
205
203
|
include AttrBaseModifier
|
206
|
-
include AttrCoerceToSymbol
|
207
|
-
def name; :reader ; end
|
204
|
+
include AttrCoerceToSymbol
|
208
205
|
def default
|
209
206
|
@attr_symbol
|
210
207
|
end
|
@@ -213,7 +210,6 @@ module MooseX
|
|
213
210
|
class Writter
|
214
211
|
include AttrBaseModifier
|
215
212
|
|
216
|
-
def name; :writter ; end
|
217
213
|
def default
|
218
214
|
@attr_symbol.to_s.concat("=").to_sym
|
219
215
|
end
|
@@ -228,18 +224,15 @@ module MooseX
|
|
228
224
|
include AttrBaseModifier
|
229
225
|
include AttrCoerceMethodToLambda
|
230
226
|
|
231
|
-
def name; :builder ; end
|
232
227
|
def default
|
233
228
|
"build_#{@attr_symbol}".to_sym
|
234
229
|
end
|
235
230
|
end
|
236
231
|
|
237
|
-
class
|
232
|
+
class Init_arg
|
238
233
|
include AttrBaseModifier
|
239
234
|
include AttrCoerceToSymbol
|
240
235
|
|
241
|
-
def name; :init_arg; end
|
242
|
-
|
243
236
|
def default
|
244
237
|
@attr_symbol
|
245
238
|
end
|
@@ -249,11 +242,9 @@ module MooseX
|
|
249
242
|
class Trigger
|
250
243
|
include AttrBaseModifier
|
251
244
|
include AttrCoerceMethodToLambda
|
252
|
-
|
253
|
-
def name; :trigger; end
|
254
245
|
|
255
246
|
def default
|
256
|
-
|
247
|
+
->(object, value) { }
|
257
248
|
end
|
258
249
|
end
|
259
250
|
|
@@ -261,16 +252,14 @@ module MooseX
|
|
261
252
|
include AttrBaseModifier
|
262
253
|
include AttrCoerceMethodToLambda
|
263
254
|
|
264
|
-
def name; :coerce; end
|
265
|
-
|
266
255
|
def default
|
267
|
-
|
256
|
+
->(object) {object}
|
268
257
|
end
|
269
258
|
|
270
259
|
def update_options(options, name, attr)
|
271
260
|
if options[:weak]
|
272
261
|
old_coerce = attr
|
273
|
-
attr =
|
262
|
+
attr = ->(value) do
|
274
263
|
WeakRef.new old_coerce.call(value)
|
275
264
|
end
|
276
265
|
end
|
@@ -282,22 +271,32 @@ module MooseX
|
|
282
271
|
class Weak
|
283
272
|
include AttrBaseModifier
|
284
273
|
include AttrCoerceToBoolean
|
285
|
-
|
286
|
-
def name; :weak ; end
|
287
274
|
end
|
288
275
|
|
289
276
|
class Doc
|
290
277
|
include AttrBaseModifier
|
291
278
|
include AttrCoerceToString
|
292
|
-
|
293
|
-
def name; :doc ; end
|
294
279
|
end
|
295
280
|
|
296
281
|
class Override
|
297
282
|
include AttrBaseModifier
|
298
283
|
include AttrCoerceToBoolean
|
284
|
+
end
|
285
|
+
|
286
|
+
class Traits
|
287
|
+
include AttrBaseModifier
|
288
|
+
def default; [] ; end
|
289
|
+
def coerce(traits,f)
|
290
|
+
original = ->(value) { value }
|
299
291
|
|
300
|
-
|
292
|
+
[ traits ].flatten.inject(original) do |inner, trait|
|
293
|
+
->(value) { trait.new inner.call value }
|
294
|
+
end
|
295
|
+
|
296
|
+
end
|
297
|
+
def validate(traits,f)
|
298
|
+
# TODO
|
299
|
+
end
|
301
300
|
end
|
302
301
|
end
|
303
302
|
end
|
data/lib/moosex/event.rb
CHANGED
data/lib/moosex/meta.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
module MooseX
|
2
2
|
|
3
3
|
class Meta
|
4
|
-
attr_reader :attrs, :requires, :hooks
|
4
|
+
attr_reader :attrs, :requires, :hooks, :plugins
|
5
5
|
|
6
6
|
def initialize(old_meta=nil)
|
7
7
|
@initialized = false
|
8
8
|
@attrs = {}
|
9
9
|
@requires = []
|
10
10
|
@roles = []
|
11
|
+
@plugins = []
|
11
12
|
|
12
13
|
@hooks = {
|
13
14
|
before: Hash.new { |hash, key| hash[key] = [] },
|
@@ -20,6 +21,7 @@ module MooseX
|
|
20
21
|
@attrs[key] = value.clone
|
21
22
|
end
|
22
23
|
@requires = old_meta.requires.clone
|
24
|
+
@plugins = old_meta.plugins.clone
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
@@ -39,6 +41,7 @@ module MooseX
|
|
39
41
|
@attrs[key] = value.clone
|
40
42
|
end
|
41
43
|
@requires += other_meta.requires
|
44
|
+
@plugins += other_meta.plugins
|
42
45
|
end
|
43
46
|
|
44
47
|
def load_from_klass(klass)
|
@@ -49,6 +52,7 @@ module MooseX
|
|
49
52
|
@hooks[hook][m] += b.clone
|
50
53
|
end
|
51
54
|
end
|
55
|
+
@plugins += other_meta.plugins
|
52
56
|
end
|
53
57
|
|
54
58
|
def add(attr)
|
@@ -111,6 +115,11 @@ module MooseX
|
|
111
115
|
end
|
112
116
|
end
|
113
117
|
end
|
118
|
+
|
119
|
+
def add_plugin(plugin)
|
120
|
+
@plugins << plugin.to_sym
|
121
|
+
end
|
122
|
+
|
114
123
|
private
|
115
124
|
def __moosex__init_hooks(method_name, method)
|
116
125
|
|
@@ -118,11 +127,11 @@ module MooseX
|
|
118
127
|
after = @hooks[:after][method_name]
|
119
128
|
around = @hooks[:around][method_name]
|
120
129
|
|
121
|
-
original =
|
130
|
+
original = ->(object, *args, &proc) do
|
122
131
|
method.bind(object).call(*args, &proc)
|
123
132
|
end
|
124
133
|
|
125
|
-
|
134
|
+
->(*args, &proc) do
|
126
135
|
before.each{|b| b.call(self,*args, &proc)}
|
127
136
|
|
128
137
|
result = around.inject(original) do |lambda1, lambda2|
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module MooseX
|
4
|
+
module Traits
|
5
|
+
class Counter < SimpleDelegator
|
6
|
+
def initialize(value)
|
7
|
+
@value = value
|
8
|
+
super(@value)
|
9
|
+
end
|
10
|
+
|
11
|
+
def inc(by=1)
|
12
|
+
@value += by
|
13
|
+
__setobj__(@value)
|
14
|
+
@value
|
15
|
+
end
|
16
|
+
|
17
|
+
def dec(by=1)
|
18
|
+
@value -= by
|
19
|
+
__setobj__(@value)
|
20
|
+
@value
|
21
|
+
end
|
22
|
+
|
23
|
+
def reset(to=0)
|
24
|
+
@value = to
|
25
|
+
__setobj__(@value)
|
26
|
+
@value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Pair < SimpleDelegator
|
31
|
+
attr_reader :first, :second
|
32
|
+
|
33
|
+
def initialize(pair)
|
34
|
+
@first, @second = pair[0], pair[1]
|
35
|
+
super([@first, @second ])
|
36
|
+
end
|
37
|
+
|
38
|
+
def first=(first_value)
|
39
|
+
@first = first_value
|
40
|
+
__setobj__([@first, @second ])
|
41
|
+
end
|
42
|
+
def second=(second_value)
|
43
|
+
@second = second_value
|
44
|
+
__setobj__([@first, @second ])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Bool < SimpleDelegator
|
49
|
+
def initialize(value)
|
50
|
+
@value = value
|
51
|
+
super(value)
|
52
|
+
end
|
53
|
+
|
54
|
+
def toggle!
|
55
|
+
@value = self.not
|
56
|
+
__setobj__(@value)
|
57
|
+
end
|
58
|
+
|
59
|
+
def set!
|
60
|
+
@value = true
|
61
|
+
__setobj__(@value)
|
62
|
+
end
|
63
|
+
|
64
|
+
def unset!
|
65
|
+
@value = false
|
66
|
+
__setobj__(@value)
|
67
|
+
end
|
68
|
+
|
69
|
+
def not
|
70
|
+
! @value
|
71
|
+
end
|
72
|
+
|
73
|
+
def value
|
74
|
+
! self.not
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class RescueToNil < SimpleDelegator
|
79
|
+
|
80
|
+
def initialize(value)
|
81
|
+
@value = value
|
82
|
+
@default_value = -> { nil }
|
83
|
+
__setobj__(@value)
|
84
|
+
end
|
85
|
+
|
86
|
+
def method_missing(m, *args, &block)
|
87
|
+
begin
|
88
|
+
super(m, *args, &block)
|
89
|
+
rescue NoMethodError
|
90
|
+
@default_value.call
|
91
|
+
rescue Exception
|
92
|
+
raise
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class RescueToZero < RescueToNil
|
98
|
+
|
99
|
+
def initialize(value)
|
100
|
+
super(value)
|
101
|
+
@default_value = ->{ 0 }
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
class RescueToEmptyString < RescueToNil
|
107
|
+
|
108
|
+
def initialize(value)
|
109
|
+
super(value)
|
110
|
+
@default_value = -> { "" }
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/lib/moosex/types.rb
CHANGED
@@ -182,7 +182,7 @@ module MooseX
|
|
182
182
|
|
183
183
|
def isTuple(*types)
|
184
184
|
|
185
|
-
size_validation =
|
185
|
+
size_validation = ->(tuple) do
|
186
186
|
unless tuple.size == types.size
|
187
187
|
raise TypeCheckError, "Tuple violation: size should be #{types.size} instead #{tuple.size}"
|
188
188
|
end
|
@@ -204,7 +204,7 @@ module MooseX
|
|
204
204
|
|
205
205
|
proc = isAllOf(
|
206
206
|
isArray(type),
|
207
|
-
|
207
|
+
->(set) do
|
208
208
|
if set.uniq.size != set.size
|
209
209
|
raise TypeCheckError, "Set violation: has one or more non unique elements"
|
210
210
|
end
|
@@ -218,7 +218,7 @@ module MooseX
|
|
218
218
|
def create_individual_validations_for_tuples(types)
|
219
219
|
individual_validations = []
|
220
220
|
types.each_index do |index|
|
221
|
-
individual_validations <<
|
221
|
+
individual_validations << ->(tuple) do
|
222
222
|
begin
|
223
223
|
isType(types[index]).call(tuple[index])
|
224
224
|
rescue TypeCheckError => e
|
data/lib/moosex/version.rb
CHANGED
data/samples/events.rb
CHANGED
data/samples/point.rb
CHANGED
data/spec/baz_spec.rb
CHANGED
@@ -6,7 +6,7 @@ class Baz
|
|
6
6
|
|
7
7
|
has bam: {
|
8
8
|
is: :ro, # read-only, you should specify in new only
|
9
|
-
isa:
|
9
|
+
isa: ->(bam) do # you should add your own validator
|
10
10
|
raise 'bam should be less than 100' if bam > 100
|
11
11
|
end,
|
12
12
|
required: true,
|