virtus2 2.0.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 +7 -0
- data/.gitignore +39 -0
- data/.rspec +2 -0
- data/.yardopts +1 -0
- data/CONTRIBUTING.md +18 -0
- data/Changelog.md +258 -0
- data/Gemfile +10 -0
- data/Guardfile +19 -0
- data/LICENSE +20 -0
- data/README.md +630 -0
- data/Rakefile +15 -0
- data/TODO.md +6 -0
- data/lib/virtus/attribute/accessor.rb +103 -0
- data/lib/virtus/attribute/boolean.rb +55 -0
- data/lib/virtus/attribute/builder.rb +182 -0
- data/lib/virtus/attribute/coercer.rb +45 -0
- data/lib/virtus/attribute/coercible.rb +20 -0
- data/lib/virtus/attribute/collection.rb +103 -0
- data/lib/virtus/attribute/default_value/from_callable.rb +35 -0
- data/lib/virtus/attribute/default_value/from_clonable.rb +35 -0
- data/lib/virtus/attribute/default_value/from_symbol.rb +35 -0
- data/lib/virtus/attribute/default_value.rb +51 -0
- data/lib/virtus/attribute/embedded_value.rb +67 -0
- data/lib/virtus/attribute/enum.rb +45 -0
- data/lib/virtus/attribute/hash.rb +130 -0
- data/lib/virtus/attribute/lazy_default.rb +18 -0
- data/lib/virtus/attribute/nullify_blank.rb +24 -0
- data/lib/virtus/attribute/strict.rb +26 -0
- data/lib/virtus/attribute.rb +245 -0
- data/lib/virtus/attribute_set.rb +240 -0
- data/lib/virtus/builder/hook_context.rb +51 -0
- data/lib/virtus/builder.rb +133 -0
- data/lib/virtus/class_inclusions.rb +48 -0
- data/lib/virtus/class_methods.rb +90 -0
- data/lib/virtus/coercer.rb +41 -0
- data/lib/virtus/configuration.rb +72 -0
- data/lib/virtus/const_missing_extensions.rb +18 -0
- data/lib/virtus/extensions.rb +105 -0
- data/lib/virtus/instance_methods.rb +218 -0
- data/lib/virtus/model.rb +68 -0
- data/lib/virtus/module_extensions.rb +88 -0
- data/lib/virtus/support/equalizer.rb +128 -0
- data/lib/virtus/support/options.rb +113 -0
- data/lib/virtus/support/type_lookup.rb +109 -0
- data/lib/virtus/value_object.rb +150 -0
- data/lib/virtus/version.rb +3 -0
- data/lib/virtus.rb +310 -0
- data/spec/integration/attributes_attribute_spec.rb +28 -0
- data/spec/integration/building_module_spec.rb +90 -0
- data/spec/integration/collection_member_coercion_spec.rb +96 -0
- data/spec/integration/custom_attributes_spec.rb +42 -0
- data/spec/integration/custom_collection_attributes_spec.rb +101 -0
- data/spec/integration/default_values_spec.rb +87 -0
- data/spec/integration/defining_attributes_spec.rb +86 -0
- data/spec/integration/embedded_value_spec.rb +50 -0
- data/spec/integration/extending_objects_spec.rb +35 -0
- data/spec/integration/hash_attributes_coercion_spec.rb +54 -0
- data/spec/integration/inheritance_spec.rb +42 -0
- data/spec/integration/injectible_coercers_spec.rb +48 -0
- data/spec/integration/mass_assignment_with_accessors_spec.rb +44 -0
- data/spec/integration/overriding_virtus_spec.rb +46 -0
- data/spec/integration/required_attributes_spec.rb +25 -0
- data/spec/integration/struct_as_embedded_value_spec.rb +28 -0
- data/spec/integration/using_modules_spec.rb +55 -0
- data/spec/integration/value_object_with_custom_constructor_spec.rb +42 -0
- data/spec/integration/virtus/instance_level_attributes_spec.rb +23 -0
- data/spec/integration/virtus/value_object_spec.rb +99 -0
- data/spec/shared/constants_helpers.rb +9 -0
- data/spec/shared/freeze_method_behavior.rb +40 -0
- data/spec/shared/idempotent_method_behaviour.rb +5 -0
- data/spec/shared/options_class_method.rb +19 -0
- data/spec/spec_helper.rb +41 -0
- data/spec/unit/virtus/attribute/boolean/coerce_spec.rb +43 -0
- data/spec/unit/virtus/attribute/boolean/value_coerced_predicate_spec.rb +25 -0
- data/spec/unit/virtus/attribute/class_methods/build_spec.rb +180 -0
- data/spec/unit/virtus/attribute/class_methods/coerce_spec.rb +32 -0
- data/spec/unit/virtus/attribute/coerce_spec.rb +129 -0
- data/spec/unit/virtus/attribute/coercible_predicate_spec.rb +20 -0
- data/spec/unit/virtus/attribute/collection/class_methods/build_spec.rb +105 -0
- data/spec/unit/virtus/attribute/collection/coerce_spec.rb +74 -0
- data/spec/unit/virtus/attribute/collection/value_coerced_predicate_spec.rb +31 -0
- data/spec/unit/virtus/attribute/comparison_spec.rb +20 -0
- data/spec/unit/virtus/attribute/custom_collection_spec.rb +29 -0
- data/spec/unit/virtus/attribute/defined_spec.rb +20 -0
- data/spec/unit/virtus/attribute/embedded_value/class_methods/build_spec.rb +70 -0
- data/spec/unit/virtus/attribute/embedded_value/coerce_spec.rb +91 -0
- data/spec/unit/virtus/attribute/get_spec.rb +32 -0
- data/spec/unit/virtus/attribute/hash/class_methods/build_spec.rb +106 -0
- data/spec/unit/virtus/attribute/hash/coerce_spec.rb +92 -0
- data/spec/unit/virtus/attribute/lazy_predicate_spec.rb +20 -0
- data/spec/unit/virtus/attribute/rename_spec.rb +16 -0
- data/spec/unit/virtus/attribute/required_predicate_spec.rb +19 -0
- data/spec/unit/virtus/attribute/set_default_value_spec.rb +107 -0
- data/spec/unit/virtus/attribute/set_spec.rb +29 -0
- data/spec/unit/virtus/attribute/value_coerced_predicate_spec.rb +19 -0
- data/spec/unit/virtus/attribute_set/append_spec.rb +47 -0
- data/spec/unit/virtus/attribute_set/define_reader_method_spec.rb +36 -0
- data/spec/unit/virtus/attribute_set/define_writer_method_spec.rb +36 -0
- data/spec/unit/virtus/attribute_set/each_spec.rb +65 -0
- data/spec/unit/virtus/attribute_set/element_reference_spec.rb +17 -0
- data/spec/unit/virtus/attribute_set/element_set_spec.rb +64 -0
- data/spec/unit/virtus/attribute_set/merge_spec.rb +34 -0
- data/spec/unit/virtus/attribute_set/reset_spec.rb +71 -0
- data/spec/unit/virtus/attribute_spec.rb +229 -0
- data/spec/unit/virtus/attributes_reader_spec.rb +41 -0
- data/spec/unit/virtus/attributes_writer_spec.rb +51 -0
- data/spec/unit/virtus/class_methods/finalize_spec.rb +67 -0
- data/spec/unit/virtus/class_methods/new_spec.rb +39 -0
- data/spec/unit/virtus/config_spec.rb +13 -0
- data/spec/unit/virtus/element_reader_spec.rb +21 -0
- data/spec/unit/virtus/element_writer_spec.rb +19 -0
- data/spec/unit/virtus/freeze_spec.rb +41 -0
- data/spec/unit/virtus/model_spec.rb +197 -0
- data/spec/unit/virtus/module_spec.rb +174 -0
- data/spec/unit/virtus/set_default_attributes_spec.rb +32 -0
- data/spec/unit/virtus/value_object_spec.rb +138 -0
- data/virtus2.gemspec +26 -0
- metadata +225 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
module Virtus
|
2
|
+
|
3
|
+
# Extensions common for both classes and instances
|
4
|
+
module Extensions
|
5
|
+
WRITER_METHOD_REGEXP = /=\z/.freeze
|
6
|
+
INVALID_WRITER_METHODS = %w[ == != === []= attributes= ].to_set.freeze
|
7
|
+
RESERVED_NAMES = [:attributes].to_set.freeze
|
8
|
+
|
9
|
+
# A hook called when an object is extended with Virtus
|
10
|
+
#
|
11
|
+
# @param [Object] object
|
12
|
+
#
|
13
|
+
# @return [undefined]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
def self.extended(object)
|
17
|
+
super
|
18
|
+
object.instance_eval do
|
19
|
+
extend Methods
|
20
|
+
extend InstanceMethods
|
21
|
+
extend InstanceMethods::MassAssignment
|
22
|
+
end
|
23
|
+
end
|
24
|
+
private_class_method :extended
|
25
|
+
|
26
|
+
module Methods
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
def self.extended(descendant)
|
30
|
+
super
|
31
|
+
descendant.extend(AttributeSet.create(descendant))
|
32
|
+
end
|
33
|
+
private_class_method :extended
|
34
|
+
|
35
|
+
# Defines an attribute on an object's class or instance
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# class Book
|
39
|
+
# include Virtus.model
|
40
|
+
#
|
41
|
+
# attribute :title, String
|
42
|
+
# attribute :author, String
|
43
|
+
# attribute :published_at, DateTime
|
44
|
+
# attribute :page_count, Integer
|
45
|
+
# attribute :index # defaults to Object
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# @param [Symbol] name
|
49
|
+
# the name of an attribute
|
50
|
+
#
|
51
|
+
# @param [Class,Array,Hash,Axiom::Types::Type,String,Symbol] type
|
52
|
+
# the type class of an attribute
|
53
|
+
#
|
54
|
+
# @param [#to_hash] options
|
55
|
+
# the extra options hash
|
56
|
+
#
|
57
|
+
# @return [self]
|
58
|
+
#
|
59
|
+
# @see Attribute.build
|
60
|
+
#
|
61
|
+
# @api public
|
62
|
+
def attribute(name, type = nil, options = {})
|
63
|
+
assert_valid_name(name)
|
64
|
+
attribute_set << Attribute.build(type, options.merge(:name => name))
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
# @see Virtus.default_value
|
69
|
+
#
|
70
|
+
# @api public
|
71
|
+
def values(&block)
|
72
|
+
private :attributes= if instance_methods.include?(:attributes=)
|
73
|
+
yield
|
74
|
+
include(Equalizer.new(name, attribute_set.map(&:name)))
|
75
|
+
end
|
76
|
+
|
77
|
+
# The list of writer methods that can be mass-assigned to in #attributes=
|
78
|
+
#
|
79
|
+
# @return [Set]
|
80
|
+
#
|
81
|
+
# @api private
|
82
|
+
def allowed_writer_methods
|
83
|
+
@allowed_writer_methods ||=
|
84
|
+
begin
|
85
|
+
allowed_writer_methods = allowed_methods.grep(WRITER_METHOD_REGEXP).to_set
|
86
|
+
allowed_writer_methods -= INVALID_WRITER_METHODS
|
87
|
+
allowed_writer_methods.freeze
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
# Return an attribute set for that instance
|
94
|
+
#
|
95
|
+
# @return [AttributeSet]
|
96
|
+
#
|
97
|
+
# @api private
|
98
|
+
def attribute_set
|
99
|
+
@attribute_set
|
100
|
+
end
|
101
|
+
|
102
|
+
end # Methods
|
103
|
+
|
104
|
+
end # module Extensions
|
105
|
+
end # module Virtus
|
@@ -0,0 +1,218 @@
|
|
1
|
+
module Virtus
|
2
|
+
|
3
|
+
# Instance methods that are added when you include Virtus
|
4
|
+
module InstanceMethods
|
5
|
+
|
6
|
+
module Constructor
|
7
|
+
|
8
|
+
# Set attributes during initialization of an object
|
9
|
+
#
|
10
|
+
# @param [#to_hash] attributes
|
11
|
+
# the attributes hash to be set
|
12
|
+
#
|
13
|
+
# @return [undefined]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
def initialize(attributes = nil)
|
17
|
+
attribute_set.set(self, attributes) if attributes
|
18
|
+
set_default_attributes
|
19
|
+
end
|
20
|
+
|
21
|
+
end # Constructor
|
22
|
+
|
23
|
+
module MassAssignment
|
24
|
+
|
25
|
+
# Returns a hash of all publicly accessible attributes
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# class User
|
29
|
+
# include Virtus
|
30
|
+
#
|
31
|
+
# attribute :name, String
|
32
|
+
# attribute :age, Integer
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# user = User.new(:name => 'John', :age => 28)
|
36
|
+
# user.attributes # => { :name => 'John', :age => 28 }
|
37
|
+
#
|
38
|
+
# @return [Hash]
|
39
|
+
#
|
40
|
+
# @api public
|
41
|
+
def attributes
|
42
|
+
attribute_set.get(self)
|
43
|
+
end
|
44
|
+
alias_method :to_hash, :attributes
|
45
|
+
alias_method :to_h, :attributes
|
46
|
+
|
47
|
+
# Mass-assign attribute values
|
48
|
+
#
|
49
|
+
# Keys in the +attributes+ param can be symbols or strings.
|
50
|
+
# All referenced Attribute writer methods *will* be called.
|
51
|
+
# Non-attribute setter methods on the receiver *will* be called.
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
# class User
|
55
|
+
# include Virtus
|
56
|
+
#
|
57
|
+
# attribute :name, String
|
58
|
+
# attribute :age, Integer
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# user = User.new
|
62
|
+
# user.attributes = { :name => 'John', 'age' => 28 }
|
63
|
+
#
|
64
|
+
# @param [#to_hash] attributes
|
65
|
+
# a hash of attribute names and values to set on the receiver
|
66
|
+
#
|
67
|
+
# @return [Hash]
|
68
|
+
#
|
69
|
+
# @api public
|
70
|
+
def attributes=(attributes)
|
71
|
+
attribute_set.set(self, attributes)
|
72
|
+
end
|
73
|
+
|
74
|
+
end # MassAssignment
|
75
|
+
|
76
|
+
# Returns a value of the attribute with the given name
|
77
|
+
#
|
78
|
+
# @example
|
79
|
+
# class User
|
80
|
+
# include Virtus
|
81
|
+
#
|
82
|
+
# attribute :name, String
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# user = User.new(:name => 'John')
|
86
|
+
# user[:name] # => "John"
|
87
|
+
#
|
88
|
+
# @param [Symbol] name
|
89
|
+
# a name of an attribute
|
90
|
+
#
|
91
|
+
# @return [Object]
|
92
|
+
# a value of an attribute
|
93
|
+
#
|
94
|
+
# @api public
|
95
|
+
def [](name)
|
96
|
+
public_send(name)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Sets a value of the attribute with the given name
|
100
|
+
#
|
101
|
+
# @example
|
102
|
+
# class User
|
103
|
+
# include Virtus
|
104
|
+
#
|
105
|
+
# attribute :name, String
|
106
|
+
# end
|
107
|
+
#
|
108
|
+
# user = User.new
|
109
|
+
# user[:name] = "John" # => "John"
|
110
|
+
# user.name # => "John"
|
111
|
+
#
|
112
|
+
# @param [Symbol] name
|
113
|
+
# a name of an attribute
|
114
|
+
#
|
115
|
+
# @param [Object] value
|
116
|
+
# a value to be set
|
117
|
+
#
|
118
|
+
# @return [Object]
|
119
|
+
# the value set on an object
|
120
|
+
#
|
121
|
+
# @api public
|
122
|
+
def []=(name, value)
|
123
|
+
public_send("#{name}=", value)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Freeze object
|
127
|
+
#
|
128
|
+
# @return [self]
|
129
|
+
#
|
130
|
+
# @api public
|
131
|
+
#
|
132
|
+
# @example
|
133
|
+
#
|
134
|
+
# class User
|
135
|
+
# include Virtus
|
136
|
+
#
|
137
|
+
# attribute :name, String
|
138
|
+
# attribute :age, Integer
|
139
|
+
# end
|
140
|
+
#
|
141
|
+
# user = User.new(:name => 'John', :age => 28)
|
142
|
+
# user.frozen? # => false
|
143
|
+
# user.freeze
|
144
|
+
# user.frozen? # => true
|
145
|
+
#
|
146
|
+
# @api public
|
147
|
+
def freeze
|
148
|
+
set_default_attributes!
|
149
|
+
super
|
150
|
+
end
|
151
|
+
|
152
|
+
# Reset an attribute to its default
|
153
|
+
#
|
154
|
+
# @return [self]
|
155
|
+
#
|
156
|
+
# @api public
|
157
|
+
#
|
158
|
+
# @example
|
159
|
+
#
|
160
|
+
# class User
|
161
|
+
# include Virtus
|
162
|
+
#
|
163
|
+
# attribute :age, Integer, default: 21
|
164
|
+
# end
|
165
|
+
#
|
166
|
+
# user = User.new(:name => 'John', :age => 28)
|
167
|
+
# user.age = 30
|
168
|
+
# user.age # => 30
|
169
|
+
# user.reset_attribute(:age)
|
170
|
+
# user.age # => 21
|
171
|
+
#
|
172
|
+
# @api public
|
173
|
+
def reset_attribute(attribute_name)
|
174
|
+
attribute = attribute_set[attribute_name]
|
175
|
+
attribute.set_default_value(self) if attribute
|
176
|
+
self
|
177
|
+
end
|
178
|
+
|
179
|
+
# Set default attributes
|
180
|
+
#
|
181
|
+
# @return [self]
|
182
|
+
#
|
183
|
+
# @api private
|
184
|
+
def set_default_attributes
|
185
|
+
attribute_set.set_defaults(self)
|
186
|
+
self
|
187
|
+
end
|
188
|
+
|
189
|
+
# Set default attributes even lazy ones
|
190
|
+
#
|
191
|
+
# @return [self]
|
192
|
+
#
|
193
|
+
# @api public
|
194
|
+
def set_default_attributes!
|
195
|
+
attribute_set.set_defaults(self, proc { |object, attribute| attribute.defined?(object) })
|
196
|
+
self
|
197
|
+
end
|
198
|
+
|
199
|
+
private
|
200
|
+
|
201
|
+
# The list of allowed public methods
|
202
|
+
#
|
203
|
+
# @return [Array<String>]
|
204
|
+
#
|
205
|
+
# @api private
|
206
|
+
def allowed_methods
|
207
|
+
public_methods.map(&:to_s)
|
208
|
+
end
|
209
|
+
|
210
|
+
# @api private
|
211
|
+
def assert_valid_name(name)
|
212
|
+
if respond_to?(:attributes) && name.to_sym == :attributes || name.to_sym == :attribute_set
|
213
|
+
raise ArgumentError, "#{name.inspect} is not allowed as an attribute name"
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
end # module InstanceMethods
|
218
|
+
end # module Virtus
|
data/lib/virtus/model.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
module Virtus
|
2
|
+
|
3
|
+
module Model
|
4
|
+
|
5
|
+
# @api private
|
6
|
+
def self.included(descendant)
|
7
|
+
super
|
8
|
+
descendant.send(:include, ClassInclusions)
|
9
|
+
end
|
10
|
+
|
11
|
+
# @api private
|
12
|
+
def self.extended(descendant)
|
13
|
+
super
|
14
|
+
descendant.extend(Extensions)
|
15
|
+
end
|
16
|
+
|
17
|
+
module Core
|
18
|
+
|
19
|
+
# @api private
|
20
|
+
def self.included(descendant)
|
21
|
+
super
|
22
|
+
descendant.extend(ClassMethods)
|
23
|
+
descendant.send(:include, ClassInclusions::Methods)
|
24
|
+
descendant.send(:include, InstanceMethods)
|
25
|
+
end
|
26
|
+
private_class_method :included
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
def self.extended(descendant)
|
30
|
+
super
|
31
|
+
descendant.extend(Extensions::Methods)
|
32
|
+
descendant.extend(InstanceMethods)
|
33
|
+
end
|
34
|
+
private_class_method :extended
|
35
|
+
|
36
|
+
end # Core
|
37
|
+
|
38
|
+
module Constructor
|
39
|
+
|
40
|
+
# @api private
|
41
|
+
def self.included(descendant)
|
42
|
+
super
|
43
|
+
descendant.send(:include, InstanceMethods::Constructor)
|
44
|
+
end
|
45
|
+
private_class_method :included
|
46
|
+
|
47
|
+
end # Constructor
|
48
|
+
|
49
|
+
module MassAssignment
|
50
|
+
|
51
|
+
# @api private
|
52
|
+
def self.included(descendant)
|
53
|
+
super
|
54
|
+
descendant.send(:include, InstanceMethods::MassAssignment)
|
55
|
+
end
|
56
|
+
private_class_method :included
|
57
|
+
|
58
|
+
# @api private
|
59
|
+
def self.extended(descendant)
|
60
|
+
super
|
61
|
+
descendant.extend(InstanceMethods::MassAssignment)
|
62
|
+
end
|
63
|
+
private_class_method :extended
|
64
|
+
|
65
|
+
end # MassAssignment
|
66
|
+
|
67
|
+
end # Model
|
68
|
+
end # Virtus
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Virtus
|
2
|
+
|
3
|
+
# Virtus module that can define attributes for later inclusion
|
4
|
+
#
|
5
|
+
# @private
|
6
|
+
module ModuleExtensions
|
7
|
+
include ConstMissingExtensions
|
8
|
+
|
9
|
+
# @api private
|
10
|
+
def self.extended(mod)
|
11
|
+
super
|
12
|
+
setup(mod)
|
13
|
+
end
|
14
|
+
|
15
|
+
# @api private
|
16
|
+
def self.setup(mod, inclusions = [Model], attribute_definitions = [])
|
17
|
+
mod.instance_variable_set('@inclusions', inclusions)
|
18
|
+
existing_attributes = mod.instance_variable_get('@attribute_definitions')
|
19
|
+
new_attributes = (existing_attributes || []) + attribute_definitions
|
20
|
+
mod.instance_variable_set('@attribute_definitions', new_attributes)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Define an attribute in the module
|
24
|
+
#
|
25
|
+
# @see Virtus::Extensions#attribute
|
26
|
+
#
|
27
|
+
# @return [self]
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
def attribute(name, type = nil, options = {})
|
31
|
+
@attribute_definitions << [name, type, options]
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Extend an object with Virtus methods and define attributes
|
38
|
+
#
|
39
|
+
# @param [Object] object
|
40
|
+
#
|
41
|
+
# @return [undefined]
|
42
|
+
#
|
43
|
+
# @api private
|
44
|
+
def extended(object)
|
45
|
+
super
|
46
|
+
@inclusions.each { |mod| object.extend(mod) }
|
47
|
+
define_attributes(object)
|
48
|
+
object.set_default_attributes
|
49
|
+
end
|
50
|
+
|
51
|
+
# Extend a class with Virtus methods and define attributes
|
52
|
+
#
|
53
|
+
# @param [Object] object
|
54
|
+
#
|
55
|
+
# @return [undefined]
|
56
|
+
#
|
57
|
+
# @api private
|
58
|
+
def included(object)
|
59
|
+
super
|
60
|
+
|
61
|
+
if Class === object
|
62
|
+
@inclusions.reject do |mod|
|
63
|
+
object.ancestors.include?(mod)
|
64
|
+
end.each do |mod|
|
65
|
+
object.send(:include, mod)
|
66
|
+
end
|
67
|
+
define_attributes(object)
|
68
|
+
else
|
69
|
+
object.extend(ModuleExtensions)
|
70
|
+
ModuleExtensions.setup(object, @inclusions, @attribute_definitions)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Define attributes on a class or instance
|
75
|
+
#
|
76
|
+
# @param [Object,Class] object
|
77
|
+
#
|
78
|
+
# @return [undefined]
|
79
|
+
#
|
80
|
+
# @api private
|
81
|
+
def define_attributes(object)
|
82
|
+
@attribute_definitions.each do |attribute_args|
|
83
|
+
object.attribute(*attribute_args)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end # module ModuleExtensions
|
88
|
+
end # module Virtus
|