virtus 0.0.10 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. data/.gitignore +33 -7
  2. data/.travis.yml +4 -74
  3. data/Changelog.md +11 -2
  4. data/Gemfile +10 -9
  5. data/README.md +85 -1
  6. data/TODO +18 -0
  7. data/config/flay.yml +2 -2
  8. data/config/flog.yml +1 -1
  9. data/config/roodi.yml +3 -3
  10. data/config/site.reek +8 -3
  11. data/lib/virtus.rb +5 -0
  12. data/lib/virtus/attribute.rb +137 -30
  13. data/lib/virtus/attribute/array.rb +17 -1
  14. data/lib/virtus/attribute/boolean.rb +8 -13
  15. data/lib/virtus/attribute/collection.rb +96 -0
  16. data/lib/virtus/attribute/default_value.rb +11 -7
  17. data/lib/virtus/attribute/embedded_value.rb +70 -0
  18. data/lib/virtus/attribute/set.rb +25 -0
  19. data/lib/virtus/attribute_set.rb +18 -16
  20. data/lib/virtus/attributes_accessor.rb +66 -0
  21. data/lib/virtus/class_methods.rb +50 -28
  22. data/lib/virtus/coercion/array.rb +23 -0
  23. data/lib/virtus/coercion/string.rb +10 -4
  24. data/lib/virtus/instance_methods.rb +38 -31
  25. data/lib/virtus/support/options.rb +6 -8
  26. data/lib/virtus/support/type_lookup.rb +4 -11
  27. data/lib/virtus/version.rb +1 -1
  28. data/spec/integration/collection_member_coercion_spec.rb +75 -0
  29. data/spec/integration/custom_attributes_spec.rb +49 -0
  30. data/spec/integration/default_values_spec.rb +32 -0
  31. data/spec/integration/defining_attributes_spec.rb +79 -0
  32. data/spec/integration/embedded_value_spec.rb +50 -0
  33. data/spec/integration/overriding_virtus_spec.rb +46 -0
  34. data/spec/integration/virtus/instance_level_attributes_spec.rb +23 -0
  35. data/spec/rcov.opts +1 -0
  36. data/spec/shared/constants_helpers.rb +9 -0
  37. data/spec/shared/options_class_method.rb +19 -0
  38. data/spec/spec_helper.rb +20 -7
  39. data/spec/unit/virtus/attribute/array/coerce_spec.rb +13 -0
  40. data/spec/unit/virtus/attribute/boolean/coerce_spec.rb +85 -0
  41. data/spec/unit/virtus/attribute/boolean/define_reader_method_spec.rb +15 -0
  42. data/spec/unit/virtus/attribute/boolean/value_coerced_spec.rb +97 -0
  43. data/spec/unit/virtus/attribute/boolean_spec.rb +2 -81
  44. data/spec/unit/virtus/attribute/class/coerce_spec.rb +13 -0
  45. data/spec/unit/virtus/attribute/class_methods/accessor_spec.rb +12 -0
  46. data/spec/unit/virtus/attribute/class_methods/build_spec.rb +37 -0
  47. data/spec/unit/virtus/attribute/class_methods/coercion_method_spec.rb +9 -0
  48. data/spec/unit/virtus/attribute/class_methods/default_spec.rb +9 -0
  49. data/spec/unit/virtus/attribute/class_methods/determine_type_spec.rb +31 -1
  50. data/spec/unit/virtus/attribute/class_methods/merge_options_spec.rb +11 -0
  51. data/spec/unit/virtus/attribute/class_methods/primitive_spec.rb +9 -0
  52. data/spec/unit/virtus/attribute/class_methods/reader_spec.rb +9 -0
  53. data/spec/unit/virtus/attribute/class_methods/writer_spec.rb +9 -0
  54. data/spec/unit/virtus/attribute/coerce_spec.rb +30 -0
  55. data/spec/unit/virtus/attribute/coercion_method_spec.rb +12 -0
  56. data/spec/unit/virtus/attribute/collection/class_methods/merge_options_spec.rb +40 -0
  57. data/spec/unit/virtus/attribute/collection/coerce_spec.rb +26 -0
  58. data/spec/unit/virtus/attribute/date/coerce_spec.rb +47 -0
  59. data/spec/unit/virtus/attribute/date/value_coerced_spec.rb +46 -0
  60. data/spec/unit/virtus/attribute/date_time/coerce_spec.rb +68 -0
  61. data/spec/unit/virtus/attribute/decimal/coerce_spec.rb +117 -0
  62. data/spec/unit/virtus/attribute/default_spec.rb +32 -0
  63. data/spec/unit/virtus/attribute/default_value/attribute_spec.rb +11 -0
  64. data/spec/unit/virtus/attribute/default_value/class_methods/new_spec.rb +4 -2
  65. data/spec/unit/virtus/attribute/default_value/evaluate_spec.rb +51 -0
  66. data/spec/unit/virtus/attribute/default_value/instance_methods/evaluate_spec.rb +9 -6
  67. data/spec/unit/virtus/attribute/default_value/value_spec.rb +11 -0
  68. data/spec/unit/virtus/attribute/define_accessor_methods_spec.rb +26 -0
  69. data/spec/unit/virtus/attribute/define_reader_method_spec.rb +24 -0
  70. data/spec/unit/virtus/attribute/define_writer_method_spec.rb +24 -0
  71. data/spec/unit/virtus/attribute/embedded_value/class_methods/merge_options_spec.rb +17 -0
  72. data/spec/unit/virtus/attribute/embedded_value/coerce_spec.rb +50 -0
  73. data/spec/unit/virtus/attribute/float/coerce_spec.rb +117 -0
  74. data/spec/unit/virtus/attribute/get_spec.rb +80 -0
  75. data/spec/unit/virtus/attribute/inspect_spec.rb +27 -0
  76. data/spec/unit/virtus/attribute/instance_variable_name_spec.rb +12 -0
  77. data/spec/unit/virtus/attribute/integer/coerce_spec.rb +105 -0
  78. data/spec/unit/virtus/attribute/name_spec.rb +12 -0
  79. data/spec/unit/virtus/attribute/numeric/class_methods/descendants_spec.rb +1 -1
  80. data/spec/unit/virtus/attribute/numeric/class_methods/max_spec.rb +9 -0
  81. data/spec/unit/virtus/attribute/numeric/class_methods/min_spec.rb +9 -0
  82. data/spec/unit/virtus/attribute/object/class_methods/descendants_spec.rb +9 -7
  83. data/spec/unit/virtus/attribute/options_spec.rb +14 -0
  84. data/spec/unit/virtus/attribute/public_reader_spec.rb +24 -0
  85. data/spec/unit/virtus/attribute/public_writer_spec.rb +24 -0
  86. data/spec/unit/virtus/attribute/reader_visibility_spec.rb +24 -0
  87. data/spec/unit/virtus/attribute/set/coerce_spec.rb +13 -0
  88. data/spec/unit/virtus/attribute/set_spec.rb +49 -0
  89. data/spec/unit/virtus/attribute/string/coerce_spec.rb +11 -0
  90. data/spec/unit/virtus/attribute/time/coerce_spec.rb +67 -0
  91. data/spec/unit/virtus/attribute/value_coerced_spec.rb +19 -0
  92. data/spec/unit/virtus/attribute/writer_visibility_spec.rb +24 -0
  93. data/spec/unit/virtus/attribute_set/append_spec.rb +12 -0
  94. data/spec/unit/virtus/attribute_set/element_reference_spec.rb +4 -0
  95. data/spec/unit/virtus/attribute_set/element_set_spec.rb +29 -9
  96. data/spec/unit/virtus/attributes_accessor/inspect_spec.rb +9 -0
  97. data/spec/unit/virtus/class_methods/attribute_spec.rb +23 -5
  98. data/spec/unit/virtus/class_methods/attributes_spec.rb +3 -5
  99. data/spec/unit/virtus/class_methods/const_missing_spec.rb +27 -0
  100. data/spec/unit/virtus/class_methods/inherited_spec.rb +21 -0
  101. data/spec/unit/virtus/coercion/array/to_set_spec.rb +12 -0
  102. data/spec/unit/virtus/coercion/date/class_methods/to_date_spec.rb +10 -0
  103. data/spec/unit/virtus/coercion/date_time/class_methods/to_datetime_spec.rb +10 -0
  104. data/spec/unit/virtus/coercion/hash/class_methods/to_date_spec.rb +10 -3
  105. data/spec/unit/virtus/coercion/hash/class_methods/to_datetime_spec.rb +10 -3
  106. data/spec/unit/virtus/coercion/hash/class_methods/to_time_spec.rb +10 -3
  107. data/spec/unit/virtus/coercion/object/class_methods/method_missing_spec.rb +8 -8
  108. data/spec/unit/virtus/coercion/string/class_methods/to_boolean_spec.rb +2 -2
  109. data/spec/unit/virtus/coercion/string/class_methods/to_constant_spec.rb +1 -1
  110. data/spec/unit/virtus/coercion/string/class_methods/to_date_spec.rb +1 -1
  111. data/spec/unit/virtus/coercion/string/class_methods/to_datetime_spec.rb +13 -13
  112. data/spec/unit/virtus/coercion/string/class_methods/to_decimal_spec.rb +25 -1
  113. data/spec/unit/virtus/coercion/string/class_methods/to_float_spec.rb +25 -1
  114. data/spec/unit/virtus/coercion/string/class_methods/to_integer_spec.rb +30 -1
  115. data/spec/unit/virtus/coercion/string/class_methods/to_time_spec.rb +13 -13
  116. data/spec/unit/virtus/coercion/time/class_methods/to_time_spec.rb +10 -0
  117. data/spec/unit/virtus/coercion/true_class/class_methods/to_string_spec.rb +1 -1
  118. data/spec/unit/virtus/instance_methods/attributes_spec.rb +77 -20
  119. data/spec/unit/virtus/instance_methods/element_reference_spec.rb +1 -1
  120. data/spec/unit/virtus/instance_methods/element_set_spec.rb +2 -2
  121. data/spec/unit/virtus/instance_methods/to_hash_spec.rb +23 -0
  122. data/spec/unit/virtus/options/accept_options_spec.rb +10 -11
  123. data/spec/unit/virtus/options/accepted_options_spec.rb +1 -1
  124. data/spec/unit/virtus/options/options_spec.rb +27 -4
  125. data/tasks/metrics/ci.rake +2 -1
  126. data/tasks/metrics/heckle.rake +207 -0
  127. data/tasks/spec.rake +14 -7
  128. data/virtus.gemspec +1 -1
  129. metadata +111 -97
  130. data/VERSION +0 -1
  131. data/examples/custom_coercion_spec.rb +0 -50
  132. data/examples/default_values_spec.rb +0 -21
  133. data/examples/override_attribute_methods_spec.rb +0 -40
  134. data/spec/integration/virtus/attributes/attribute/set_spec.rb +0 -36
  135. data/spec/integration/virtus/class_methods/attribute_spec.rb +0 -82
  136. data/spec/integration/virtus/class_methods/attributes_spec.rb +0 -22
  137. data/spec/integration/virtus/class_methods/const_missing_spec.rb +0 -44
  138. data/spec/unit/shared/attribute.rb +0 -7
  139. data/spec/unit/shared/attribute/accept_options.rb +0 -37
  140. data/spec/unit/shared/attribute/accepted_options.rb +0 -5
  141. data/spec/unit/shared/attribute/get.rb +0 -44
  142. data/spec/unit/shared/attribute/inspect.rb +0 -7
  143. data/spec/unit/shared/attribute/set.rb +0 -37
  144. data/spec/unit/virtus/attribute/array_spec.rb +0 -24
  145. data/spec/unit/virtus/attribute/class_spec.rb +0 -24
  146. data/spec/unit/virtus/attribute/date_spec.rb +0 -59
  147. data/spec/unit/virtus/attribute/date_time_spec.rb +0 -87
  148. data/spec/unit/virtus/attribute/decimal_spec.rb +0 -109
  149. data/spec/unit/virtus/attribute/float_spec.rb +0 -109
  150. data/spec/unit/virtus/attribute/hash_spec.rb +0 -11
  151. data/spec/unit/virtus/attribute/integer_spec.rb +0 -99
  152. data/spec/unit/virtus/attribute/string_spec.rb +0 -21
  153. data/spec/unit/virtus/attribute/time_spec.rb +0 -82
  154. data/spec/unit/virtus/class_methods/new_spec.rb +0 -41
@@ -12,10 +12,26 @@ module Virtus
12
12
  #
13
13
  # post = Post.new(:tags => %w(red green blue))
14
14
  #
15
- class Array < Object
15
+ class Array < Collection
16
16
  primitive ::Array
17
17
  coercion_method :to_array
18
18
 
19
+ # Coerce a member of a source collection and append it to the target collection
20
+ #
21
+ # @param [Array, Set] collection
22
+ # target collection to which the coerced member should be appended
23
+ #
24
+ # @param [Object] entry
25
+ # the member that should be coerced and appended
26
+ #
27
+ # @return [Array, Set]
28
+ # collection with the coerced member appended to it
29
+ #
30
+ # @api private
31
+ def coerce_and_append_member(collection, entry)
32
+ collection << @member_type_instance.coerce(entry)
33
+ end
34
+
19
35
  end # class Array
20
36
  end # class Attribute
21
37
  end # module Virtus
@@ -21,19 +21,20 @@ module Virtus
21
21
  # Returns if the given value is either true or false
22
22
  #
23
23
  # @example
24
- # Virtus::Attribute::Boolean.primitive?(true) # => true
25
- # Virtus::Attribute::Boolean.primitive?(false) # => true
26
- # Virtus::Attribute::Boolean.primitive?(1) # => false
27
- # Virtus::Attribute::Boolean.primitive?('true') # => false
24
+ # boolean = Virtus::Attribute::Boolean.new(:bool)
25
+ # boolean.value_coerced?(true) # => true
26
+ # boolean.value_coerced?(false) # => true
27
+ # boolean.value_coerced?(1) # => false
28
+ # boolean.value_coerced?('true') # => false
28
29
  #
29
30
  # @return [Boolean]
30
31
  #
31
32
  # @api public
32
- def self.primitive?(value)
33
+ def value_coerced?(value)
33
34
  value.equal?(true) || value.equal?(false)
34
35
  end
35
36
 
36
- # Creates standard and boolean attribute reader methods
37
+ # Creates an attribute reader method as a query
37
38
  #
38
39
  # @param [Module] mod
39
40
  #
@@ -42,13 +43,7 @@ module Virtus
42
43
  # @api private
43
44
  def define_reader_method(mod)
44
45
  super
45
-
46
- reader_method_name = "#{name}?"
47
- attribute = self
48
-
49
- mod.send(:define_method, reader_method_name) { attribute.get(self) }
50
- mod.send(reader_visibility, reader_method_name)
51
-
46
+ mod.define_reader_method(self, "#{name}?", reader_visibility)
52
47
  self
53
48
  end
54
49
 
@@ -0,0 +1,96 @@
1
+ module Virtus
2
+ class Attribute
3
+
4
+ # Abstract superclass for collection Attributes.
5
+ #
6
+ # Handles coercing members to the designated member type.
7
+ #
8
+ # @abstract
9
+ class Collection < Object
10
+
11
+ # The type to which members of this collection will be coerced
12
+ #
13
+ # @example
14
+ #
15
+ # class Post
16
+ # include Virtus
17
+ #
18
+ # attribute :tags, Array[String]
19
+ # end
20
+ #
21
+ # Post.attributes[:tags].member_type # => Virtus::Attribute::String
22
+ #
23
+ # @return [Virtus::Attribute]
24
+ #
25
+ # @api public
26
+ attr_reader :member_type
27
+
28
+ # Handles collection with member_type syntax
29
+ #
30
+ # @param [Class]
31
+ #
32
+ # @param [Hash]
33
+ #
34
+ # @return [Hash]
35
+ #
36
+ # @api private
37
+ def self.merge_options(type, options)
38
+ if !type.respond_to?(:size)
39
+ options
40
+ elsif type.size > 1
41
+ raise NotImplementedError, "build SumType from list of types (#{type.inspect})"
42
+ else
43
+ options.merge(:member_type => type.first)
44
+ end
45
+ end
46
+
47
+ # Init an instance of Virtus::Attribute::Collection
48
+ #
49
+ # @api private
50
+ def initialize(*)
51
+ super
52
+ @member_type = @options.fetch(:member_type, Virtus::Attribute::Object)
53
+ @member_type_instance = Attribute.build(@name, @member_type)
54
+ end
55
+
56
+ # Coerce a collection with members
57
+ #
58
+ # @param [Object]
59
+ #
60
+ # @return [Object]
61
+ #
62
+ # @api private
63
+ def coerce(value)
64
+ coerced = super
65
+ return coerced unless coerced.respond_to?(:inject)
66
+ coerced.inject(new_collection) do |collection, entry|
67
+ coerce_and_append_member(collection, entry)
68
+ end
69
+ end
70
+
71
+ # Return an instance of the collection
72
+ #
73
+ # @return [Enumerable]
74
+ #
75
+ # @api private
76
+ def new_collection
77
+ self.class.primitive.new
78
+ end
79
+
80
+ # Coerce entry and add it to the collection
81
+ #
82
+ # @abstract
83
+ #
84
+ # @raise NotImplementedError
85
+ #
86
+ # @return [undefined]
87
+ #
88
+ # @api private
89
+ def coerce_and_append_member(collection, entry)
90
+ raise NotImplementedError,
91
+ "#{self.class}#coerce_and_append_member has not been implemented"
92
+ end
93
+
94
+ end # class Array
95
+ end # class Attribute
96
+ end # module Virtus
@@ -3,8 +3,8 @@ module Virtus
3
3
 
4
4
  # Class representing the default value option
5
5
  class DefaultValue
6
- DUP_CLASSES = [ ::NilClass, ::TrueClass, ::FalseClass,
7
- ::Numeric, ::Symbol ].freeze
6
+ SINGLETON_CLASSES = [ ::NilClass, ::TrueClass, ::FalseClass,
7
+ ::Numeric, ::Symbol ].freeze
8
8
 
9
9
  # Returns the attribute associated with this default value instance
10
10
  #
@@ -42,8 +42,8 @@ module Virtus
42
42
  def evaluate(instance)
43
43
  if callable?
44
44
  call(instance)
45
- elsif duplicable?
46
- value.dup
45
+ elsif cloneable?
46
+ value.clone
47
47
  else
48
48
  value
49
49
  end
@@ -71,13 +71,17 @@ module Virtus
71
71
  value.respond_to?(:call)
72
72
  end
73
73
 
74
- # Returns whether or not the value is duplicable
74
+ # Returns whether or not the value is cloneable
75
75
  #
76
76
  # # return [TrueClass, FalseClass]
77
77
  #
78
78
  # @api private
79
- def duplicable?
80
- DUP_CLASSES.none? { |klass| value.kind_of?(klass) }
79
+ def cloneable?
80
+ case value
81
+ when *SINGLETON_CLASSES then false
82
+ else
83
+ true
84
+ end
81
85
  end
82
86
 
83
87
  end # class DefaultValue
@@ -0,0 +1,70 @@
1
+ require 'ostruct'
2
+
3
+ module Virtus
4
+ class Attribute
5
+
6
+ # EmbeddedValue
7
+ #
8
+ # @example
9
+ #
10
+ # class Address
11
+ # include Virtus
12
+ #
13
+ # attribute :street, String
14
+ # attribute :zipcode, String
15
+ # attribute :city, String
16
+ # end
17
+ #
18
+ # class User
19
+ # include Virtus
20
+ #
21
+ # attribute :address, Address
22
+ # end
23
+ #
24
+ # user = User.new(:address => {
25
+ # :street => 'Street 1/2', :zipcode => '12345', :city => 'NYC' })
26
+ #
27
+ class EmbeddedValue < Object
28
+
29
+ # @see Attribute.merge_options
30
+ #
31
+ # @return [Hash]
32
+ # an updated options hash for configuring an EmbeddedValue instance
33
+ #
34
+ # @api private
35
+ def self.merge_options(type, options)
36
+ options.merge(:model => type)
37
+ end
38
+
39
+ # Sets @model ivar
40
+ #
41
+ # @see Virtus::Attribute#initialize
42
+ #
43
+ # @return [undefined]
44
+ #
45
+ # @api private
46
+ def initialize(name, options = {})
47
+ super
48
+ @model = options.fetch(:model, OpenStruct)
49
+ end
50
+
51
+ # Coerce attributes into a virtus object
52
+ #
53
+ # @param [Hash,Virtus]
54
+ #
55
+ # @return [Virtus]
56
+ #
57
+ # @api private
58
+ def coerce(attributes_or_object)
59
+ value = if attributes_or_object.kind_of?(::Hash)
60
+ @model.new(attributes_or_object)
61
+ else
62
+ attributes_or_object
63
+ end
64
+
65
+ super(value)
66
+ end
67
+
68
+ end # class EmbeddedValue
69
+ end # class Attribute
70
+ end # module Virtus
@@ -0,0 +1,25 @@
1
+ module Virtus
2
+ class Attribute
3
+
4
+ # Set
5
+ #
6
+ # @example
7
+ # class Post
8
+ # include Virtus
9
+ #
10
+ # attribute :tags, Set
11
+ # end
12
+ #
13
+ # post = Post.new(:tags => %w(red green blue))
14
+ #
15
+ class Set < Collection
16
+ primitive ::Set
17
+ coercion_method :to_set
18
+
19
+ def coerce_and_append_member(collection, entry)
20
+ collection << @member_type_instance.coerce(entry)
21
+ end
22
+
23
+ end # class Set
24
+ end # class Attribute
25
+ end # module Virtus
@@ -24,9 +24,10 @@ module Virtus
24
24
  #
25
25
  # @api private
26
26
  def initialize(parent = nil, attributes = [])
27
- @parent = parent
28
- @attributes = attributes.dup
29
- @index = {}
27
+ @parent = parent
28
+ @attributes = attributes.dup
29
+ @index = {}
30
+ @string_index = {}
30
31
  reset
31
32
  end
32
33
 
@@ -91,7 +92,7 @@ module Virtus
91
92
  #
92
93
  # @api public
93
94
  def [](name)
94
- @index[name]
95
+ @index.fetch(name) { @string_index[name] }
95
96
  end
96
97
 
97
98
  # Set an attribute by name
@@ -106,9 +107,8 @@ module Virtus
106
107
  #
107
108
  # @api public
108
109
  def []=(name, attribute)
109
- delete(name)
110
110
  @attributes << attribute
111
- @index[name] = attribute
111
+ update_index(name, attribute)
112
112
  end
113
113
 
114
114
  # Reset the index when the parent is updated
@@ -118,33 +118,35 @@ module Virtus
118
118
  # @api private
119
119
  def reset
120
120
  parent = self.parent
121
- merge_index(parent) if parent
122
- merge_index(@attributes)
121
+ merge_attributes(parent) if parent
122
+ merge_attributes(@attributes)
123
123
  self
124
124
  end
125
125
 
126
126
  private
127
127
 
128
- # Delete the Attribute by name
128
+ # Merge the attributes into the index
129
129
  #
130
- # @param [Symbol] name
130
+ # @param [Array<Attribute>] attributes
131
131
  #
132
132
  # @return [undefined]
133
133
  #
134
134
  # @api private
135
- def delete(name)
136
- @attributes.delete(@index.delete(name))
135
+ def merge_attributes(attributes)
136
+ attributes.each { |attribute| update_index(attribute.name, attribute) }
137
137
  end
138
138
 
139
- # Add the attributes to the index
139
+ # Update the symbol and string indexes with the attribute
140
140
  #
141
- # @param [Array<Attribute>] attributes
141
+ # @param [Symbol] name
142
+ #
143
+ # @param [Attribute] attribute
142
144
  #
143
145
  # @return [undefined]
144
146
  #
145
147
  # @api private
146
- def merge_index(attributes)
147
- attributes.each { |attribute| @index[attribute.name] = attribute }
148
+ def update_index(name, attribute)
149
+ @index[name] = @string_index[name.to_s.freeze] = attribute
148
150
  end
149
151
 
150
152
  end # class AttributeSet
@@ -0,0 +1,66 @@
1
+ module Virtus
2
+
3
+ # Host attribute accessor methods
4
+ class AttributesAccessor < Module
5
+
6
+ # The inspect value of this Module
7
+ #
8
+ # This provides meaningful output when inspecting the ancestors
9
+ # of a class/module that includes this module
10
+ #
11
+ # @example
12
+ #
13
+ # class ClassWithAttributes
14
+ # include Virtus
15
+ # end
16
+ #
17
+ # mod = ClassWithAttributes.send(:virtus_setup_attributes_accessor_module)
18
+ # mod.inspect
19
+ #
20
+ # @return [String]
21
+ #
22
+ # @api public
23
+ attr_reader :inspect
24
+
25
+ # Initialize a module for hosting Attribute access methods
26
+ #
27
+ # @param [Symbol, String] name
28
+ #
29
+ # @api private
30
+ def initialize(name)
31
+ super()
32
+ @inspect = "#{name}::AttributesAccessor"
33
+ end
34
+
35
+ # Defines an attribute reader method
36
+ #
37
+ # @param [Attribute] attribute
38
+ # @param [Symbol] method_name
39
+ # @param [Symbol] visibility
40
+ #
41
+ # @return [self]
42
+ #
43
+ # @api private
44
+ def define_reader_method(attribute, method_name, visibility)
45
+ define_method(method_name) { attribute.get(self) }
46
+ send(visibility, method_name)
47
+ self
48
+ end
49
+
50
+ # Defines an attribute writer method
51
+ #
52
+ # @param [Attribute] attribute
53
+ # @param [Symbol] method_name
54
+ # @param [Symbol] visibility
55
+ #
56
+ # @return [self]
57
+ #
58
+ # @api private
59
+ def define_writer_method(attribute, method_name, visibility)
60
+ define_method(method_name) { |value| attribute.set(self, value) }
61
+ send(visibility, method_name)
62
+ self
63
+ end
64
+
65
+ end
66
+ end