virtus 1.0.0.beta8 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog.md +28 -1
- data/LICENSE +1 -1
- data/README.md +12 -22
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/mutant.yml +2 -1
- data/config/reek.yml +67 -17
- data/lib/virtus.rb +61 -5
- data/lib/virtus/attribute.rb +107 -26
- data/lib/virtus/attribute/builder.rb +42 -34
- data/lib/virtus/attribute/collection.rb +11 -6
- data/lib/virtus/attribute/embedded_value.rb +12 -7
- data/lib/virtus/attribute/hash.rb +19 -8
- data/lib/virtus/attribute_set.rb +2 -13
- data/lib/virtus/builder.rb +137 -0
- data/lib/virtus/builder/hook_context.rb +51 -0
- data/lib/virtus/class_inclusions.rb +1 -0
- data/lib/virtus/class_methods.rb +1 -5
- data/lib/virtus/configuration.rb +12 -2
- data/lib/virtus/extensions.rb +28 -32
- data/lib/virtus/instance_methods.rb +2 -2
- data/lib/virtus/model.rb +3 -1
- data/lib/virtus/module_extensions.rb +1 -1
- data/lib/virtus/value_object.rb +1 -1
- data/lib/virtus/version.rb +1 -1
- data/spec/integration/inheritance_spec.rb +42 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/virtus/attribute/collection/class_methods/build_spec.rb +10 -0
- data/spec/unit/virtus/attribute/hash/class_methods/build_spec.rb +14 -0
- data/spec/unit/virtus/class_methods/finalize_spec.rb +10 -4
- data/spec/unit/virtus/model_spec.rb +35 -3
- data/spec/unit/virtus/module_spec.rb +44 -3
- data/spec/unit/virtus/value_object_spec.rb +39 -22
- data/virtus.gemspec +2 -1
- metadata +9 -6
- data/lib/virtus/module_builder.rb +0 -192
data/Changelog.md
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
# v1.0.0 [to-be-released]
|
2
|
+
|
3
|
+
This release no longer works with Ruby 1.8.7.
|
4
|
+
|
5
|
+
* [BREAKING CHANGE] Integrated with axiom-types, most of the attribute sub-classes are gone (solnic)
|
6
|
+
* [feature] Configurable coercion via coercible integration (solnic)
|
7
|
+
* [feature] Strict mode for coercions via `:strict` option (solnic)
|
8
|
+
* [feature] Lazy-loaded default values via `:lazy` option (solnic)
|
9
|
+
* [feature] Finalizing models solving circular-dependency issue (see #81) (solnic)
|
10
|
+
* [feature] Ability to cherry-pick which extension should be included (solnic)
|
11
|
+
* [feature] Ability to inject a custom coercer object via `:coercer` option (solnic)
|
12
|
+
* [feature] Extension module builder with pre-defined configuration for attributes (elskwid & solnic)
|
13
|
+
* [feature] `Virtus::Attribute` exposes a public API - you can easily build, rename and clone attribute instances and use their coercion power (solnic)
|
14
|
+
* [feature] Ability to reset attributes to their default values (pewniak747)
|
15
|
+
* [changed] A meaningful error will be raised if a reserved name is used as an attribute name (solnic)
|
16
|
+
* [changed] Default value can be set via private and protected methods now (solnic)
|
17
|
+
* [changed] New syntax for value objects (solnic)
|
18
|
+
* [deprecated] `Virtus::Attribute.coerce` in favor of `Virtus.coerce` or a customized configured module (solnic)
|
19
|
+
* [deprecated] `include Virtus` in favor of `include Virtus.model` (for classes) or `Virtus.module` (for modules) (solnic)
|
20
|
+
* [deprecated] `include Virtus::ValueObject` in favor of `include Virtus.value_object` (solnic)
|
21
|
+
* [deprecated] `Virtus#attributes` in favor of `Virtus#attribute_set` (solnic)
|
22
|
+
* [fixed] const missing hook now works correctly in modules too (cored)
|
23
|
+
* [fixed] value object with Hash type works correctly (solnic)
|
24
|
+
* [fixed] issues with value-object subclasses and `#==` method (solnic)
|
25
|
+
|
26
|
+
[Compare v0.5.4..master](https://github.com/solnic/virtus/compare/v0.5.4...master)
|
27
|
+
|
1
28
|
# v0.5.4 2012-12-20
|
2
29
|
|
3
30
|
* [feature] Allow *any* enumerable to be a collection attribute (aptinio)
|
@@ -12,7 +39,7 @@
|
|
12
39
|
* [feature] Added Hash member type coercion [example](https://github.com/solnic/virtus#hash-attributes-coercion) (greyblake)
|
13
40
|
* [fixed] Fixed issues with String=>Integer coercion and e-notation (greyblake)
|
14
41
|
* [changed] Replaced internal DescendantsTracker with the extracted gem (solnic)
|
15
|
-
* [
|
42
|
+
* [internal] Switched to rspec 2 and mutant for mutation testing (mbj)
|
16
43
|
|
17
44
|
[Compare v0.5.2..v0.5.3](https://github.com/solnic/virtus/compare/v0.5.2...v0.5.3)
|
18
45
|
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -69,46 +69,36 @@ user.age # => 21
|
|
69
69
|
### Cherry-picking extensions
|
70
70
|
|
71
71
|
``` ruby
|
72
|
-
# include
|
72
|
+
# include attribute DSL + constructor + mass-assignment
|
73
73
|
class User
|
74
|
-
include Virtus
|
74
|
+
include Virtus.model
|
75
75
|
|
76
76
|
attribute :name, String
|
77
77
|
end
|
78
78
|
|
79
|
-
user = User.new
|
80
|
-
user.
|
79
|
+
user = User.new(:name => 'Piotr')
|
80
|
+
user.attributes = { :name => 'John' }
|
81
|
+
user.attributes
|
82
|
+
# => {:name => 'John'}
|
81
83
|
|
82
84
|
# include attribute DSL + constructor
|
83
85
|
class User
|
84
|
-
include Virtus
|
85
|
-
include Virtus::Model::Constructor
|
86
|
+
include Virtus.model(:mass_assignment => false)
|
86
87
|
|
87
88
|
attribute :name, String
|
88
89
|
end
|
89
90
|
|
90
91
|
User.new(:name => 'Piotr')
|
91
92
|
|
92
|
-
# include attribute DSL
|
93
|
+
# include just the attribute DSL
|
93
94
|
class User
|
94
|
-
include Virtus
|
95
|
-
include Virtus::Model::Constructor
|
96
|
-
include Virtus::Model::MassAssignment
|
95
|
+
include Virtus.model(:constructor => false, :mass_assignment => false)
|
97
96
|
|
98
97
|
attribute :name, String
|
99
98
|
end
|
100
99
|
|
101
|
-
user = User.new
|
102
|
-
user.
|
103
|
-
user.attributes
|
104
|
-
# => {:name => 'John'}
|
105
|
-
|
106
|
-
# starting from virtus 1.0.0 preferred way to do this is to use module builder
|
107
|
-
MyModel = Virtus.model(:constructor => false, :mass_assignment => false)
|
108
|
-
|
109
|
-
class User
|
110
|
-
include MyModel
|
111
|
-
end
|
100
|
+
user = User.new
|
101
|
+
user.name = 'Piotr'
|
112
102
|
```
|
113
103
|
|
114
104
|
### Using Virtus with Modules
|
@@ -525,7 +515,7 @@ end
|
|
525
515
|
## Attribute Finalization and Circular Dependencies
|
526
516
|
|
527
517
|
If a type references another type which happens to not be available yet you need
|
528
|
-
to use lazy-finalization of attributes and finalize virtus manually after all
|
518
|
+
to use lazy-finalization of attributes and finalize virtus manually after all
|
529
519
|
types have been already loaded:
|
530
520
|
|
531
521
|
``` ruby
|
data/config/flay.yml
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
---
|
2
|
-
threshold:
|
3
|
-
total_score:
|
2
|
+
threshold: 24
|
3
|
+
total_score: 439
|
data/config/flog.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
---
|
2
|
-
threshold:
|
2
|
+
threshold: 33
|
data/config/mutant.yml
CHANGED
@@ -3,12 +3,13 @@ name: virtus
|
|
3
3
|
namespace:
|
4
4
|
- 'Virtus::Attribute'
|
5
5
|
- 'Virtus::AttributeSet'
|
6
|
+
- 'Virtus::Builder'
|
6
7
|
- 'Virtus::ClassInclusions'
|
7
8
|
- 'Virtus::ClassMethods'
|
8
9
|
- 'Virtus::Configuration'
|
9
10
|
- 'Virtus::ConstMissingExtensions'
|
10
11
|
- 'Virtus::Extensions'
|
11
12
|
- 'Virtus::InstanceMethods'
|
12
|
-
- 'Virtus::
|
13
|
+
- 'Virtus::Model'
|
13
14
|
- 'Virtus::ModuleExtensions'
|
14
15
|
- 'Virtus::ValueObject'
|
data/config/reek.yml
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
---
|
2
2
|
Attribute:
|
3
|
-
enabled:
|
4
|
-
exclude: []
|
3
|
+
enabled: false
|
5
4
|
BooleanParameter:
|
6
5
|
enabled: true
|
7
6
|
exclude: []
|
@@ -10,23 +9,39 @@ ClassVariable:
|
|
10
9
|
exclude: []
|
11
10
|
ControlParameter:
|
12
11
|
enabled: true
|
13
|
-
exclude:
|
12
|
+
exclude:
|
13
|
+
- 'Virtus::InstanceMethods::Constructor#initialize'
|
14
14
|
DataClump:
|
15
15
|
enabled: true
|
16
|
-
exclude: []
|
17
16
|
max_copies: 2
|
18
17
|
min_clump_size: 2
|
18
|
+
exclude:
|
19
|
+
- 'Virtus::AttributeSet'
|
19
20
|
DuplicateMethodCall:
|
20
21
|
enabled: false
|
21
22
|
FeatureEnvy:
|
22
23
|
enabled: true
|
23
|
-
exclude:
|
24
|
+
exclude:
|
25
|
+
- 'Virtus::Attribute::Boolean#value_coerced?'
|
26
|
+
- 'Virtus::AttributeSet#get'
|
27
|
+
- 'Virtus::AttributeSet#set'
|
28
|
+
- 'Virtus::AttributeSet#skip_default?'
|
29
|
+
- 'Virtus::Builder#add_extended_hook'
|
30
|
+
- 'Virtus::Builder#add_included_hook'
|
31
|
+
- 'Virtus::InstanceMethods#assert_valid_name'
|
32
|
+
- 'Virtus::TypeLookup#determine_type_from_primitive'
|
24
33
|
IrresponsibleModule:
|
25
34
|
enabled: true
|
26
35
|
exclude: []
|
27
36
|
LongParameterList:
|
28
37
|
enabled: true
|
29
|
-
exclude:
|
38
|
+
exclude:
|
39
|
+
- 'Virtus::AttributeSet#define_reader_method'
|
40
|
+
- 'Virtus::AttributeSet#define_writer_method'
|
41
|
+
- 'Virtus::Extensions::Methods#attribute'
|
42
|
+
- 'Virtus::ModuleExtensions#attribute'
|
43
|
+
- 'Virtus::ModuleExtensions#self.setup'
|
44
|
+
- 'Virtus::ValueObject::ClassMethods#attribute'
|
30
45
|
max_params: 2
|
31
46
|
LongYieldList:
|
32
47
|
enabled: true
|
@@ -36,34 +51,65 @@ NestedIterators:
|
|
36
51
|
enabled: true
|
37
52
|
max_allowed_nesting: 1
|
38
53
|
ignore_iterators: []
|
39
|
-
exclude:
|
54
|
+
exclude:
|
55
|
+
- 'Virtus::Builder#add_extended_hook'
|
56
|
+
- 'Virtus::Builder#add_included_hook'
|
57
|
+
- 'Virtus::ModuleBuilder#add_included_hook'
|
58
|
+
- 'Virtus::Equalizer#define_cmp_method'
|
59
|
+
- 'Virtus::Equalizer#define_hash_method'
|
60
|
+
- 'Virtus::Equalizer#define_inspect_method'
|
40
61
|
NilCheck:
|
41
62
|
enabled: true
|
42
|
-
exclude:
|
63
|
+
exclude:
|
64
|
+
- 'Virtus::Attribute::EmbeddedValue::FromOpenStruct#call'
|
65
|
+
- 'Virtus::Attribute::EmbeddedValue::FromStruct#call'
|
66
|
+
- 'Virtus::Attribute::Strict#coerce'
|
67
|
+
- 'Virtus::Options#options'
|
68
|
+
- 'Virtus::TypeLookup#determine_type_from_primitive'
|
43
69
|
RepeatedConditional:
|
44
70
|
enabled: true
|
45
|
-
exclude: []
|
46
71
|
max_ifs: 1
|
72
|
+
exclude:
|
73
|
+
- 'Virtus::AttributeSet'
|
74
|
+
- 'Virtus::Builder'
|
47
75
|
TooManyInstanceVariables:
|
48
76
|
enabled: true
|
49
|
-
exclude: []
|
50
77
|
max_instance_variables: 3
|
78
|
+
exclude:
|
79
|
+
- 'Virtus::Attribute'
|
80
|
+
- 'Virtus::Attribute::Builder'
|
81
|
+
- 'Virtus::Configuration'
|
51
82
|
TooManyMethods:
|
52
83
|
enabled: true
|
53
|
-
|
54
|
-
|
84
|
+
max_methods: 6
|
85
|
+
exclude:
|
86
|
+
- 'Virtus::Equalizer'
|
87
|
+
- 'Virtus::Builder'
|
88
|
+
- 'Virtus::Attribute'
|
89
|
+
- 'Virtus::AttributeSet'
|
55
90
|
TooManyStatements:
|
56
91
|
enabled: true
|
57
|
-
exclude: []
|
58
92
|
max_statements: 4
|
93
|
+
exclude:
|
94
|
+
- 'Virtus#self.included'
|
95
|
+
- 'Virtus::Attribute::Builder#self.determine_type'
|
96
|
+
- 'Virtus::Attribute::Collection#self.infer'
|
97
|
+
- 'Virtus::Attribute::Hash#self.infer'
|
98
|
+
- 'Virtus::Builder#add_extended_hook'
|
99
|
+
- 'Virtus::Builder#add_included_hook'
|
100
|
+
- 'Virtus::ModuleBuilder#add_included_hook'
|
101
|
+
- 'Virtus::ClassInclusions#self.included'
|
102
|
+
- 'Virtus::ClassMethods#self.extended'
|
103
|
+
- 'Virtus::Extensions#self.extended'
|
104
|
+
- 'Virtus::ModuleExtensions#included'
|
105
|
+
- 'Virtus::TypeLookup#determine_type_from_primitive'
|
106
|
+
- 'Virtus::ValueObject#self.included'
|
59
107
|
UncommunicativeMethodName:
|
60
108
|
enabled: true
|
61
|
-
exclude: []
|
62
109
|
reject:
|
63
110
|
- !ruby/regexp /^[a-z]$/
|
64
111
|
- !ruby/regexp /[0-9]$/
|
65
112
|
- !ruby/regexp /[A-Z]/
|
66
|
-
accept: []
|
67
113
|
UncommunicativeModuleName:
|
68
114
|
enabled: true
|
69
115
|
exclude: []
|
@@ -78,7 +124,7 @@ UncommunicativeParameterName:
|
|
78
124
|
- !ruby/regexp /^.$/
|
79
125
|
- !ruby/regexp /[0-9]$/
|
80
126
|
- !ruby/regexp /[A-Z]/
|
81
|
-
accept: []
|
127
|
+
accept: ['_']
|
82
128
|
UncommunicativeVariableName:
|
83
129
|
enabled: true
|
84
130
|
exclude: []
|
@@ -92,5 +138,9 @@ UnusedParameters:
|
|
92
138
|
exclude: []
|
93
139
|
UtilityFunction:
|
94
140
|
enabled: true
|
95
|
-
exclude: []
|
96
141
|
max_helper_calls: 0
|
142
|
+
exclude:
|
143
|
+
- 'Virtus::Attribute::Boolean#value_coerced?'
|
144
|
+
- 'Virtus::AttributeSet#set_default'
|
145
|
+
- 'Virtus::AttributeSet#skip_default?'
|
146
|
+
- 'Virtus::Extensions::Methods#merge_options'
|
data/lib/virtus.rb
CHANGED
@@ -25,6 +25,8 @@ module Virtus
|
|
25
25
|
#
|
26
26
|
# @return [undefined]
|
27
27
|
#
|
28
|
+
# @deprecated
|
29
|
+
#
|
28
30
|
# @api private
|
29
31
|
def self.included(object)
|
30
32
|
super
|
@@ -44,6 +46,8 @@ module Virtus
|
|
44
46
|
#
|
45
47
|
# @return [undefined]
|
46
48
|
#
|
49
|
+
# @deprecated
|
50
|
+
#
|
47
51
|
# @api private
|
48
52
|
def self.extended(object)
|
49
53
|
Virtus.warn("extending with Virtus module is deprecated. Use 'extend(Virtus.model)' instead #{caller.first}")
|
@@ -124,21 +128,53 @@ module Virtus
|
|
124
128
|
#
|
125
129
|
# @api public
|
126
130
|
def self.model(options = {}, &block)
|
127
|
-
|
131
|
+
ModelBuilder.call(options, &block)
|
128
132
|
end
|
129
133
|
|
130
134
|
# Builds a module for...modules
|
131
135
|
#
|
136
|
+
# @example
|
137
|
+
#
|
138
|
+
# module Common
|
139
|
+
# include Virtus.module
|
140
|
+
#
|
141
|
+
# attribute :name, String
|
142
|
+
# attribute :age, Integer
|
143
|
+
# end
|
144
|
+
#
|
145
|
+
# class User
|
146
|
+
# include Common
|
147
|
+
# end
|
148
|
+
#
|
149
|
+
# class Admin
|
150
|
+
# include Common
|
151
|
+
# end
|
152
|
+
#
|
153
|
+
# @return [Module]
|
154
|
+
#
|
132
155
|
# @api public
|
133
156
|
def self.module(options = {}, &block)
|
134
|
-
|
157
|
+
ModuleBuilder.call(options, &block)
|
135
158
|
end
|
136
159
|
|
137
160
|
# Builds a module for value object models
|
138
161
|
#
|
162
|
+
# @example
|
163
|
+
#
|
164
|
+
# class GeoLocation
|
165
|
+
# include Virtus.value_object
|
166
|
+
#
|
167
|
+
# values do
|
168
|
+
# attribute :lat, Float
|
169
|
+
# attribute :lng, Float
|
170
|
+
# end
|
171
|
+
# end
|
172
|
+
#
|
173
|
+
# @return [Module]
|
174
|
+
#
|
139
175
|
# @api public
|
140
176
|
def self.value_object(options = {}, &block)
|
141
|
-
|
177
|
+
ValueObjectBuilder.call(options, &block)
|
142
178
|
end
|
143
179
|
|
144
180
|
# Global configuration instance
|
@@ -150,9 +186,28 @@ module Virtus
|
|
150
186
|
@configuration ||= Configuration.new
|
151
187
|
end
|
152
188
|
|
189
|
+
# Finalize pending attributes
|
190
|
+
#
|
191
|
+
# @example
|
192
|
+
# class User
|
193
|
+
# include Virtus.model(:finalize => false)
|
194
|
+
#
|
195
|
+
# attribute :address, 'Address'
|
196
|
+
# end
|
197
|
+
#
|
198
|
+
# class Address
|
199
|
+
# include Virtus.model(:finalize => false)
|
200
|
+
#
|
201
|
+
# attribute :user, 'User'
|
202
|
+
# end
|
203
|
+
#
|
204
|
+
# Virtus.finalize # this will resolve constant names
|
205
|
+
#
|
206
|
+
# @return [Array] array of finalized models
|
207
|
+
#
|
153
208
|
# @api public
|
154
209
|
def self.finalize
|
155
|
-
|
210
|
+
Builder.pending.each do |klass|
|
156
211
|
klass.attribute_set.finalize
|
157
212
|
end
|
158
213
|
end
|
@@ -180,7 +235,8 @@ require 'virtus/class_inclusions'
|
|
180
235
|
require 'virtus/module_extensions'
|
181
236
|
|
182
237
|
require 'virtus/configuration'
|
183
|
-
require 'virtus/
|
238
|
+
require 'virtus/builder'
|
239
|
+
require 'virtus/builder/hook_context'
|
184
240
|
|
185
241
|
require 'virtus/class_methods'
|
186
242
|
require 'virtus/instance_methods'
|
data/lib/virtus/attribute.rb
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
module Virtus
|
2
2
|
|
3
|
+
# Attribute objects handle coercion and provide interface to hook into an
|
4
|
+
# attribute set instance that's included into a class or object
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
#
|
8
|
+
# # non-strict mode
|
9
|
+
# attr = Virtus::Attribute.build(Integer)
|
10
|
+
# attr.coerce('1')
|
11
|
+
# # => 1
|
12
|
+
#
|
13
|
+
# # strict mode
|
14
|
+
# attr = Virtus::Attribute.build(Integer, :strict => true)
|
15
|
+
# attr.coerce('not really coercible')
|
16
|
+
# # => Virtus::CoercionError: Failed to coerce "fsafa" into Integer
|
17
|
+
#
|
3
18
|
class Attribute
|
4
19
|
extend DescendantsTracker, Options, TypeLookup
|
5
20
|
|
@@ -24,22 +39,28 @@ module Virtus
|
|
24
39
|
self
|
25
40
|
end
|
26
41
|
|
27
|
-
|
42
|
+
# Return type of this attribute
|
43
|
+
#
|
44
|
+
# @return [Axiom::Types::Type]
|
45
|
+
#
|
46
|
+
# @api public
|
47
|
+
attr_reader :type
|
48
|
+
|
49
|
+
# @api private
|
50
|
+
attr_reader :primitive, :options, :default_value, :coercer
|
28
51
|
|
29
52
|
# Builds an attribute instance
|
30
53
|
#
|
31
|
-
# @param [Symbol]
|
32
|
-
#
|
33
|
-
#
|
34
|
-
# @param [Class] type
|
35
|
-
# optional type class of an attribute
|
54
|
+
# @param [Class,Array,Hash,String,Symbol] type
|
55
|
+
# this can be an explicit class or an object from which virtus can infer
|
56
|
+
# the type
|
36
57
|
#
|
37
58
|
# @param [#to_hash] options
|
38
59
|
# optional extra options hash
|
39
60
|
#
|
40
61
|
# @return [Attribute]
|
41
62
|
#
|
42
|
-
# @api
|
63
|
+
# @api public
|
43
64
|
def self.build(type, options = {})
|
44
65
|
Builder.call(type, options)
|
45
66
|
end
|
@@ -52,13 +73,6 @@ module Virtus
|
|
52
73
|
)
|
53
74
|
end
|
54
75
|
|
55
|
-
# @api private
|
56
|
-
def self.new(*args)
|
57
|
-
attribute = super
|
58
|
-
yield(attribute)
|
59
|
-
attribute
|
60
|
-
end
|
61
|
-
|
62
76
|
# @api private
|
63
77
|
def self.build_type(definition)
|
64
78
|
Axiom::Types.infer(definition.primitive)
|
@@ -69,16 +83,6 @@ module Virtus
|
|
69
83
|
# noop
|
70
84
|
end
|
71
85
|
|
72
|
-
# Initializes an attribute instance
|
73
|
-
#
|
74
|
-
# @param [#to_sym] name
|
75
|
-
# the name of an attribute
|
76
|
-
#
|
77
|
-
# @param [#to_hash] options
|
78
|
-
# hash of extra options which overrides defaults set on an attribute class
|
79
|
-
#
|
80
|
-
# @return [undefined]
|
81
|
-
#
|
82
86
|
# @api private
|
83
87
|
def initialize(type, options)
|
84
88
|
@type = type
|
@@ -88,16 +92,37 @@ module Virtus
|
|
88
92
|
@coercer = options.fetch(:coercer)
|
89
93
|
end
|
90
94
|
|
95
|
+
# Coerce the input into the expected type
|
96
|
+
#
|
97
|
+
# @example
|
98
|
+
#
|
99
|
+
# attr = Virtus::Attribute.build(String)
|
100
|
+
# attr.coerce(:one) # => 'one'
|
101
|
+
#
|
102
|
+
# @param [Object] input
|
103
|
+
#
|
91
104
|
# @api public
|
92
|
-
def coerce(
|
93
|
-
coercer.call(
|
105
|
+
def coerce(input)
|
106
|
+
coercer.call(input)
|
94
107
|
end
|
95
108
|
|
109
|
+
# Return a new attribute with the new name
|
110
|
+
#
|
111
|
+
# @param [Symbol] name
|
112
|
+
#
|
113
|
+
# @return [Attribute]
|
114
|
+
#
|
96
115
|
# @api public
|
97
116
|
def rename(name)
|
98
117
|
self.class.build(type, options.merge(:name => name))
|
99
118
|
end
|
100
119
|
|
120
|
+
# Return if the given value was coerced
|
121
|
+
#
|
122
|
+
# @param [Object] value
|
123
|
+
#
|
124
|
+
# @return [Boolean]
|
125
|
+
#
|
101
126
|
# @api public
|
102
127
|
def value_coerced?(value)
|
103
128
|
coercer.success?(primitive, value)
|
@@ -105,6 +130,14 @@ module Virtus
|
|
105
130
|
|
106
131
|
# Return if the attribute is coercible
|
107
132
|
#
|
133
|
+
# @example
|
134
|
+
#
|
135
|
+
# attr = Virtus::Attribute.build(String, :coerce => true)
|
136
|
+
# attr.coercible? # => true
|
137
|
+
#
|
138
|
+
# attr = Virtus::Attribute.build(String, :coerce => false)
|
139
|
+
# attr.coercible? # => false
|
140
|
+
#
|
108
141
|
# @return [Boolean]
|
109
142
|
#
|
110
143
|
# @api public
|
@@ -112,21 +145,69 @@ module Virtus
|
|
112
145
|
kind_of?(Coercible)
|
113
146
|
end
|
114
147
|
|
148
|
+
# Return if the attribute has lazy default value evaluation
|
149
|
+
#
|
150
|
+
# @example
|
151
|
+
#
|
152
|
+
# attr = Virtus::Attribute.build(String, :lazy => true)
|
153
|
+
# attr.lazy? # => true
|
154
|
+
#
|
155
|
+
# attr = Virtus::Attribute.build(String, :lazy => false)
|
156
|
+
# attr.lazy? # => false
|
157
|
+
#
|
158
|
+
# @return [Boolean]
|
159
|
+
#
|
115
160
|
# @api public
|
116
161
|
def lazy?
|
117
162
|
kind_of?(LazyDefault)
|
118
163
|
end
|
119
164
|
|
165
|
+
# Return if the attribute is in the strict coercion mode
|
166
|
+
#
|
167
|
+
# @example
|
168
|
+
#
|
169
|
+
# attr = Virtus::Attribute.build(String, :strict => true)
|
170
|
+
# attr.strict? # => true
|
171
|
+
#
|
172
|
+
# attr = Virtus::Attribute.build(String, :strict => false)
|
173
|
+
# attr.strict? # => false
|
174
|
+
#
|
175
|
+
# @return [Boolean]
|
176
|
+
#
|
120
177
|
# @api public
|
121
178
|
def strict?
|
122
179
|
kind_of?(Strict)
|
123
180
|
end
|
124
181
|
|
182
|
+
# Return if the attribute is accepts nil values as valid coercion output
|
183
|
+
#
|
184
|
+
# @example
|
185
|
+
#
|
186
|
+
# attr = Virtus::Attribute.build(String, :required => true)
|
187
|
+
# attr.required? # => true
|
188
|
+
#
|
189
|
+
# attr = Virtus::Attribute.build(String, :required => false)
|
190
|
+
# attr.required? # => false
|
191
|
+
#
|
192
|
+
# @return [Boolean]
|
193
|
+
#
|
125
194
|
# @api public
|
126
195
|
def required?
|
127
196
|
options[:required]
|
128
197
|
end
|
129
198
|
|
199
|
+
# Return if the attribute was already finalized
|
200
|
+
#
|
201
|
+
# @example
|
202
|
+
#
|
203
|
+
# attr = Virtus::Attribute.build(String, :finalize => true)
|
204
|
+
# attr.finalized? # => true
|
205
|
+
#
|
206
|
+
# attr = Virtus::Attribute.build(String, :finalize => false)
|
207
|
+
# attr.finalized? # => false
|
208
|
+
#
|
209
|
+
# @return [Boolean]
|
210
|
+
#
|
130
211
|
# @api public
|
131
212
|
def finalized?
|
132
213
|
frozen?
|