virtus2 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|