motion_virtus 1.0.0.beta0
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 +15 -0
- data/README.md +445 -0
- data/lib/motion_virtus.rb +13 -0
- data/lib/project/attribute/accessor/builder.rb +69 -0
- data/lib/project/attribute/accessor/lazy_accessor.rb +39 -0
- data/lib/project/attribute/accessor.rb +100 -0
- data/lib/project/attribute/accessor_method.rb +73 -0
- data/lib/project/attribute/array.rb +24 -0
- data/lib/project/attribute/boolean.rb +52 -0
- data/lib/project/attribute/class.rb +23 -0
- data/lib/project/attribute/coercer.rb +43 -0
- data/lib/project/attribute/collection/coercible_writer.rb +83 -0
- data/lib/project/attribute/collection.rb +56 -0
- data/lib/project/attribute/date.rb +36 -0
- data/lib/project/attribute/date_time.rb +38 -0
- data/lib/project/attribute/decimal.rb +23 -0
- data/lib/project/attribute/default_value/from_callable.rb +37 -0
- data/lib/project/attribute/default_value/from_clonable.rb +37 -0
- data/lib/project/attribute/default_value/from_symbol.rb +37 -0
- data/lib/project/attribute/default_value.rb +49 -0
- data/lib/project/attribute/embedded_value/open_struct_coercer.rb +43 -0
- data/lib/project/attribute/embedded_value/struct_coercer.rb +42 -0
- data/lib/project/attribute/embedded_value.rb +69 -0
- data/lib/project/attribute/float.rb +30 -0
- data/lib/project/attribute/hash/coercible_writer.rb +78 -0
- data/lib/project/attribute/hash.rb +66 -0
- data/lib/project/attribute/integer.rb +27 -0
- data/lib/project/attribute/numeric.rb +25 -0
- data/lib/project/attribute/object.rb +13 -0
- data/lib/project/attribute/reader.rb +39 -0
- data/lib/project/attribute/set.rb +22 -0
- data/lib/project/attribute/string.rb +24 -0
- data/lib/project/attribute/symbol.rb +23 -0
- data/lib/project/attribute/time.rb +36 -0
- data/lib/project/attribute/writer/coercible.rb +45 -0
- data/lib/project/attribute/writer.rb +73 -0
- data/lib/project/attribute.rb +292 -0
- data/lib/project/attribute_set.rb +260 -0
- data/lib/project/class_inclusions.rb +41 -0
- data/lib/project/class_methods.rb +102 -0
- data/lib/project/configuration.rb +65 -0
- data/lib/project/const_missing_extensions.rb +16 -0
- data/lib/project/extensions.rb +101 -0
- data/lib/project/instance_methods.rb +165 -0
- data/lib/project/module_builder.rb +92 -0
- data/lib/project/module_extensions.rb +72 -0
- data/lib/project/stubs/date.rb +2 -0
- data/lib/project/stubs/date_time.rb +2 -0
- data/lib/project/stubs/decimal.rb +2 -0
- data/lib/project/stubs/ostruct.rb +149 -0
- data/lib/project/stubs/set.rb +767 -0
- data/lib/project/stubs.rb +5 -0
- data/lib/project/support/equalizer.rb +147 -0
- data/lib/project/support/options.rb +114 -0
- data/lib/project/support/type_lookup.rb +109 -0
- data/lib/project/value_object.rb +139 -0
- data/lib/project/version.rb +3 -0
- data/lib/project/virtus.rb +128 -0
- metadata +158 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
motion_require 'object'
|
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
|
+
primitive ::OpenStruct
|
29
|
+
|
30
|
+
# @see Attribute.merge_options
|
31
|
+
#
|
32
|
+
# @return [Hash]
|
33
|
+
# an updated options hash for configuring an EmbeddedValue instance
|
34
|
+
#
|
35
|
+
# @api private
|
36
|
+
def self.merge_options(type, _options)
|
37
|
+
super.update(:primitive => type)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Determine type based on class
|
41
|
+
#
|
42
|
+
# Virtus::EmbeddedValue.determine_type(Struct) # => Virtus::EmbeddedValue::FromStruct
|
43
|
+
# Virtus::EmbeddedValue.determine_type(VirtusClass) # => Virtus::EmbeddedValue::FromOpenStruct
|
44
|
+
#
|
45
|
+
# @param [Class] klass
|
46
|
+
#
|
47
|
+
# @return [Virtus::Attribute::EmbeddedValue]
|
48
|
+
#
|
49
|
+
# @api private
|
50
|
+
def self.determine_type(klass)
|
51
|
+
if klass <= Virtus || klass <= OpenStruct || klass <= Struct
|
52
|
+
self
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @api private
|
57
|
+
def self.coercer(type, _options = {})
|
58
|
+
if type <= Virtus || type <= OpenStruct
|
59
|
+
OpenStructCoercer.new(type)
|
60
|
+
elsif type <= Struct
|
61
|
+
StructCoercer.new(type)
|
62
|
+
else
|
63
|
+
super
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end # class EmbeddedValue
|
68
|
+
end # class Attribute
|
69
|
+
end # module Virtus
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Virtus
|
2
|
+
class Attribute
|
3
|
+
|
4
|
+
# Float
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# class ExchangeRate
|
8
|
+
# include Virtus
|
9
|
+
#
|
10
|
+
# attribute :dollar, Float
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# ExchangeRate.new(:dollar => 2.69)
|
14
|
+
#
|
15
|
+
# # typecasting from a string
|
16
|
+
# ExchangeRate.new(:dollar => '2.69')
|
17
|
+
#
|
18
|
+
# # typecasting from an integer
|
19
|
+
# ExchangeRate.new(:dollar => 2)
|
20
|
+
#
|
21
|
+
# # typecasting from an object which implements #to_f
|
22
|
+
# ExchangeRate.new(:dollar => BigDecimal.new('2.69')
|
23
|
+
#
|
24
|
+
class Float < Numeric
|
25
|
+
primitive ::Float
|
26
|
+
coercion_method :to_float
|
27
|
+
|
28
|
+
end # class Float
|
29
|
+
end # class Attribute
|
30
|
+
end # module Virtus
|
@@ -0,0 +1,78 @@
|
|
1
|
+
motion_require '../hash.rb'
|
2
|
+
|
3
|
+
module Virtus
|
4
|
+
class Attribute
|
5
|
+
class Hash
|
6
|
+
|
7
|
+
# Coercible writer for Hash attributes
|
8
|
+
#
|
9
|
+
class CoercibleWriter < Attribute::Writer::Coercible
|
10
|
+
|
11
|
+
# The type to which keys of this hash will be coerced
|
12
|
+
#
|
13
|
+
# @return [Virtus::Attribute]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
attr_reader :key_type
|
17
|
+
|
18
|
+
# The type to which values of this hash will be coerced
|
19
|
+
#
|
20
|
+
# @return [Virtus::Attribute]
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
attr_reader :value_type
|
24
|
+
|
25
|
+
# Return writer for hash keys
|
26
|
+
#
|
27
|
+
# @return [Writer::Coercible]
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
attr_reader :key_coercer
|
31
|
+
|
32
|
+
# Return writer for hash values
|
33
|
+
#
|
34
|
+
# @return [Writer::Coercible]
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
attr_reader :value_coercer
|
38
|
+
|
39
|
+
# @api private
|
40
|
+
def initialize(name, options)
|
41
|
+
super
|
42
|
+
@key_type = options.fetch(:key_type, ::Object)
|
43
|
+
@value_type = options.fetch(:value_type, ::Object)
|
44
|
+
@key_coercer = Attribute.determine_type(@key_type).coercer(@key_type)
|
45
|
+
@value_coercer = Attribute.determine_type(@value_type).coercer(@value_type)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Coerce a hash with keys and values
|
49
|
+
#
|
50
|
+
# @param [Object] value
|
51
|
+
#
|
52
|
+
# @return [Object]
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
def coerce(_value)
|
56
|
+
coerced = super
|
57
|
+
return coerced unless coerced.respond_to?(:each_with_object)
|
58
|
+
coerced.each_with_object(new_hash) do |(key, value), hash|
|
59
|
+
hash[key_coercer.call(key)] = value_coercer.call(value)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
# Return an instance of the hash
|
66
|
+
#
|
67
|
+
# @return [Hash]
|
68
|
+
#
|
69
|
+
# @api private
|
70
|
+
def new_hash
|
71
|
+
primitive.new
|
72
|
+
end
|
73
|
+
|
74
|
+
end # class CoercibleWriter
|
75
|
+
|
76
|
+
end # class Collection
|
77
|
+
end # class Attribute
|
78
|
+
end # module Virtus
|
@@ -0,0 +1,66 @@
|
|
1
|
+
motion_require 'object'
|
2
|
+
|
3
|
+
module Virtus
|
4
|
+
class Attribute
|
5
|
+
|
6
|
+
# Hash
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# class Post
|
10
|
+
# include Virtus
|
11
|
+
#
|
12
|
+
# attribute :meta, Hash
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# Post.new(:meta => { :tags => %w(foo bar) })
|
16
|
+
#
|
17
|
+
class Hash < Object
|
18
|
+
primitive ::Hash
|
19
|
+
coercion_method :to_hash
|
20
|
+
default primitive.new
|
21
|
+
|
22
|
+
# Handles hashes with [key_type => value_type] syntax
|
23
|
+
#
|
24
|
+
# @param [Class] type
|
25
|
+
#
|
26
|
+
# @param [Hash] options
|
27
|
+
#
|
28
|
+
# @return [Hash]
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
def self.merge_options(type, _options)
|
32
|
+
merged_options = super
|
33
|
+
|
34
|
+
if !type.respond_to?(:size)
|
35
|
+
merged_options
|
36
|
+
elsif type.size > 1
|
37
|
+
raise ArgumentError, "more than one [key => value] pair in `#{type.inspect}`"
|
38
|
+
else
|
39
|
+
key_type, value_type = type.first
|
40
|
+
merged_options.merge!(:key_type => key_type, :value_type => value_type)
|
41
|
+
end
|
42
|
+
|
43
|
+
merged_options
|
44
|
+
end
|
45
|
+
|
46
|
+
# @see Virtus::Attribute.coercible_writer_class
|
47
|
+
#
|
48
|
+
# @return [::Class]
|
49
|
+
#
|
50
|
+
# @api private
|
51
|
+
def self.coercible_writer_class(_type, options)
|
52
|
+
options[:key_type] && options[:value_type] ? CoercibleWriter : super
|
53
|
+
end
|
54
|
+
|
55
|
+
# @see Virtus::Attribute.writer_option_names
|
56
|
+
#
|
57
|
+
# @return [Array<Symbol>]
|
58
|
+
#
|
59
|
+
# @api private
|
60
|
+
def self.writer_option_names
|
61
|
+
super << :key_type << :value_type
|
62
|
+
end
|
63
|
+
|
64
|
+
end # class Hash
|
65
|
+
end # class Attribute
|
66
|
+
end # module Virtus
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Virtus
|
2
|
+
class Attribute
|
3
|
+
|
4
|
+
# Integer
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# class Post
|
8
|
+
# include Virtus
|
9
|
+
#
|
10
|
+
# attribute :read_count, Integer
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# Post.new(:read_count => 100)
|
14
|
+
#
|
15
|
+
# # typecasting from a string
|
16
|
+
# Post.new(:read_count => '100')
|
17
|
+
#
|
18
|
+
# # typecasting from an object that implements #to_i
|
19
|
+
# Post.new(:read_count => 100.0)
|
20
|
+
#
|
21
|
+
class Integer < Numeric
|
22
|
+
primitive ::Integer
|
23
|
+
coercion_method :to_integer
|
24
|
+
|
25
|
+
end # class Integer
|
26
|
+
end # class Attribute
|
27
|
+
end # module Virtus
|
@@ -0,0 +1,25 @@
|
|
1
|
+
motion_require 'object'
|
2
|
+
|
3
|
+
module Virtus
|
4
|
+
class Attribute
|
5
|
+
|
6
|
+
# Base class for all numerical attributes
|
7
|
+
class Numeric < Object
|
8
|
+
primitive ::Numeric
|
9
|
+
#accept_options :min, :max
|
10
|
+
|
11
|
+
def self.min(value=Undefined)
|
12
|
+
return @min if value.equal?(Undefined)
|
13
|
+
@min = value
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.max(value=Undefined)
|
18
|
+
return @max if value.equal?(Undefined)
|
19
|
+
@max = value
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
end # class Numeric
|
24
|
+
end # class Attribute
|
25
|
+
end # module Virtus
|
@@ -0,0 +1,13 @@
|
|
1
|
+
motion_require '../attribute.rb'
|
2
|
+
|
3
|
+
module Virtus
|
4
|
+
class Attribute
|
5
|
+
|
6
|
+
# Base class for every attribute
|
7
|
+
class Object < Attribute
|
8
|
+
primitive ::Object
|
9
|
+
coercion_method :to_object
|
10
|
+
|
11
|
+
end # class Object
|
12
|
+
end # class Attribute
|
13
|
+
end # module Virtus
|
@@ -0,0 +1,39 @@
|
|
1
|
+
motion_require 'accessor_method'
|
2
|
+
|
3
|
+
module Virtus
|
4
|
+
class Attribute
|
5
|
+
|
6
|
+
# Reader method object
|
7
|
+
#
|
8
|
+
# @api public
|
9
|
+
class Reader < AccessorMethod
|
10
|
+
|
11
|
+
# Returns value of an attribute for the given instance
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# attribute.get(instance) # => value
|
15
|
+
#
|
16
|
+
# @return [Object]
|
17
|
+
# value of an attribute
|
18
|
+
#
|
19
|
+
# @api public
|
20
|
+
def call(instance)
|
21
|
+
instance.instance_variable_get(instance_variable_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Creates an attribute reader method
|
25
|
+
#
|
26
|
+
# @param [Module] mod
|
27
|
+
#
|
28
|
+
# @return [self]
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
def define_method(accessor, mod)
|
32
|
+
mod.define_reader_method(accessor, name, visibility)
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
end # class Reader
|
37
|
+
|
38
|
+
end # class Attribute
|
39
|
+
end # module Virtus
|
@@ -0,0 +1,22 @@
|
|
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
|
+
default primitive.new
|
19
|
+
|
20
|
+
end # class Set
|
21
|
+
end # class Attribute
|
22
|
+
end # module Virtus
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Virtus
|
2
|
+
class Attribute
|
3
|
+
|
4
|
+
# String
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# class User
|
8
|
+
# include Virtus
|
9
|
+
#
|
10
|
+
# attribute :name, String
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# User.new(:name => 'John')
|
14
|
+
#
|
15
|
+
# # typecasting from an object which implements #to_s
|
16
|
+
# User.new(:name => :John)
|
17
|
+
#
|
18
|
+
class String < Object
|
19
|
+
primitive ::String
|
20
|
+
coercion_method :to_string
|
21
|
+
|
22
|
+
end # class String
|
23
|
+
end # class Attribute
|
24
|
+
end # module Virtus
|
@@ -0,0 +1,23 @@
|
|
1
|
+
motion_require 'object'
|
2
|
+
|
3
|
+
module Virtus
|
4
|
+
class Attribute
|
5
|
+
|
6
|
+
# Symbol
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# class Product
|
10
|
+
# include Virtus
|
11
|
+
#
|
12
|
+
# attribute :code, Symbol
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# product = Product.new(:code => :red)
|
16
|
+
#
|
17
|
+
class Symbol < Object
|
18
|
+
primitive ::Symbol
|
19
|
+
coercion_method :to_symbol
|
20
|
+
|
21
|
+
end # class Symbol
|
22
|
+
end # class Attribute
|
23
|
+
end # module Virtus
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Virtus
|
2
|
+
class Attribute
|
3
|
+
|
4
|
+
# Time
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# class Post
|
8
|
+
# include Virtus
|
9
|
+
#
|
10
|
+
# attribute :published_at, Time
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# Post.new(:published_at => Time.now)
|
14
|
+
#
|
15
|
+
# # typecasting from a string
|
16
|
+
# Post.new(:published_at => '2011/06/09 11:08')
|
17
|
+
#
|
18
|
+
# # typecasting from a hash
|
19
|
+
# Post.new(:published_at => {
|
20
|
+
# :year => 2011,
|
21
|
+
# :month => 6,
|
22
|
+
# :day => 9,
|
23
|
+
# :hour => 11,
|
24
|
+
# :min => 8,
|
25
|
+
# })
|
26
|
+
#
|
27
|
+
# # typecasting from an object which implements #to_time
|
28
|
+
# Post.new(:published_at => DateTime.now)
|
29
|
+
#
|
30
|
+
class Time < Object
|
31
|
+
primitive ::Time
|
32
|
+
coercion_method :to_time
|
33
|
+
|
34
|
+
end # class Time
|
35
|
+
end # class Attribute
|
36
|
+
end # module Virtus
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Virtus
|
2
|
+
class Attribute
|
3
|
+
class Writer < AccessorMethod
|
4
|
+
|
5
|
+
class Coercible < self
|
6
|
+
|
7
|
+
# Return coercer object used by this writer
|
8
|
+
#
|
9
|
+
# @return [Object]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
attr_reader :coercer
|
13
|
+
|
14
|
+
# @api private
|
15
|
+
def initialize(name, options = {})
|
16
|
+
super
|
17
|
+
@coercer = options.fetch(:coercer)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @api private
|
21
|
+
def call(instance, value)
|
22
|
+
super(instance, coerce(value))
|
23
|
+
end
|
24
|
+
|
25
|
+
# Converts the given value to the primitive type
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# attribute.coerce(value) # => primitive_value
|
29
|
+
#
|
30
|
+
# @param [Object] value
|
31
|
+
# the value
|
32
|
+
#
|
33
|
+
# @return [Object]
|
34
|
+
# nil, original value or value converted to the primitive type
|
35
|
+
#
|
36
|
+
# @api public
|
37
|
+
def coerce(value)
|
38
|
+
coercer.call(value)
|
39
|
+
end
|
40
|
+
|
41
|
+
end # class Coercible
|
42
|
+
|
43
|
+
end # class Writer
|
44
|
+
end # class Attribute
|
45
|
+
end # module Virtus
|
@@ -0,0 +1,73 @@
|
|
1
|
+
motion_require 'accessor_method'
|
2
|
+
|
3
|
+
module Virtus
|
4
|
+
class Attribute
|
5
|
+
|
6
|
+
# Writer method object
|
7
|
+
#
|
8
|
+
# @api public
|
9
|
+
class Writer < AccessorMethod
|
10
|
+
|
11
|
+
# Return primitive
|
12
|
+
#
|
13
|
+
# @return [Class]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
attr_reader :primitive
|
17
|
+
|
18
|
+
# Return default value instance
|
19
|
+
#
|
20
|
+
# @return [DefaultValue]
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
attr_reader :default_value
|
24
|
+
|
25
|
+
# Initialize a writer instance
|
26
|
+
#
|
27
|
+
# @param [#to_sym] name
|
28
|
+
#
|
29
|
+
# @param [Hash] options
|
30
|
+
#
|
31
|
+
# @return [undefined]
|
32
|
+
#
|
33
|
+
# @api private
|
34
|
+
def initialize(name, options = {})
|
35
|
+
super
|
36
|
+
@name = "#{name}=".to_sym
|
37
|
+
@primitive = options.fetch(:primitive, ::Object)
|
38
|
+
@default_value = DefaultValue.build(options[:default])
|
39
|
+
end
|
40
|
+
|
41
|
+
# Sets instance variable of the attribute
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# attribute.set!(instance, value) # => value
|
45
|
+
#
|
46
|
+
# @return [self]
|
47
|
+
#
|
48
|
+
# @api public
|
49
|
+
def call(instance, value)
|
50
|
+
instance.instance_variable_set(instance_variable_name, value)
|
51
|
+
end
|
52
|
+
|
53
|
+
# @api private
|
54
|
+
def set_default_value(instance, attribute)
|
55
|
+
call(instance, default_value.call(instance, attribute))
|
56
|
+
end
|
57
|
+
|
58
|
+
# Creates an attribute writer method
|
59
|
+
#
|
60
|
+
# @param [Module] mod
|
61
|
+
#
|
62
|
+
# @return [self]
|
63
|
+
#
|
64
|
+
# @api private
|
65
|
+
def define_method(accessor, mod)
|
66
|
+
mod.define_writer_method(accessor, name, visibility)
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
end # class Writer
|
71
|
+
|
72
|
+
end # class Attribute
|
73
|
+
end # module Virtus
|