This repository has been archived by the owner on Sep 18, 2019. It is now read-only.
/
attribute.rb
85 lines (68 loc) · 2.69 KB
/
attribute.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# encoding: utf-8
module Attrio
class Attribute
attr_reader :name, :type, :options, :object
def initialize(name, type, options)
@name = name; @type = type; @options = Helpers.symbolize_hash_keys(options)
end
def reader_method_name
@reader_method_name ||= self.accessor_name_from_options(:reader) || self.name
end
def writer_method_name
@writer_method_name ||= self.accessor_name_from_options(:writer) || "#{self.name}="
end
def reader_visibility
@reader_visibility ||= self.accessor_visibility_from_options(:reader) || :public
end
def writer_visibility
@writer_visibility ||= self.accessor_visibility_from_options(:writer) || :public
end
def instance_variable_name
@instance_variable_name ||= self.options[:instance_variable_name] || "@#{self.name}"
end
def default_value
if !defined?(@default_value)
@default_value = Attrio::DefaultValue.new(self.name, self.options[:default])
end
@default_value
end
def reset!
raise ArgumentError if self.object.nil?
value = self.default_value.is_a?(Attrio::DefaultValue::Base) ? self.default_value.call(self.object) : self.default_value
self.object.send(self.writer_method_name, value)
end
def default?
raise ArgumentError if self.object.nil?
value = self.default_value.is_a?(Attrio::DefaultValue::Base) ? self.default_value.call(self.object) : self.default_value
self.object.send(self.reader_method_name) == value
end
def define_writer(klass)
Attrio::Builders::WriterBuilder.define(klass, self.type,
self.options.merge({
:method_name => self.writer_method_name,
:method_visibility => self.writer_visibility,
:instance_variable_name => self.instance_variable_name
})
)
self
end
def define_reader(klass)
Attrio::Builders::ReaderBuilder.define(klass, self.type,
self.options.merge({
:method_name => self.reader_method_name,
:method_visibility => self.reader_visibility,
:instance_variable_name => self.instance_variable_name
})
)
self
end
protected
def accessor_name_from_options(accessor)
(self.options[accessor.to_sym].is_a?(Hash) && self.options[accessor.to_sym][:name]) || self.options["#{accessor.to_s}_name".to_sym]
end
def accessor_visibility_from_options(accessor)
return self.options[accessor] if self.options[accessor].present? && [:public, :protected, :private].include?(self.options[accessor])
(self.options[accessor].is_a?(Hash) && self.options[accessor][:visibility]) || self.options["#{accessor.to_s}_visibility".to_sym]
end
end
end