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
|
# File 'lib/schema/schema.rb', line 28
def attribute_macro(attribute_name, type=nil, strict: nil, default: nil)
if type.nil? && !strict.nil?
raise Schema::Attribute::Error, "The \"#{attribute_name}\" attribute is declared with the \"strict\" option but a type is not specified"
end
if type == Boolean && strict == false
raise Schema::Attribute::Error, "The \"#{attribute_name}\" attribute is declared with the \"strict\" option disabled but boolean type is specified"
end
check = nil
if type == Boolean
strict ||= true
check = proc do |val|
unless val.nil? || Boolean.(val)
raise Schema::Attribute::TypeError, "#{val.inspect} of type #{val.class.name} cannot be assigned to attribute #{attribute_name.inspect} of type Boolean (Strict: #{strict.inspect})"
end
end
elsif !type.nil?
strict ||= false
check = proc do |val|
unless val.nil?
if strict
if not val.instance_of?(type)
raise Schema::Attribute::TypeError, "#{val.inspect} of type #{val.class.name} cannot be assigned to attribute #{attribute_name.inspect} of type #{type.name} (Strict: #{strict.inspect})"
end
else
if not val.is_a?(type)
raise Schema::Attribute::TypeError, "#{val.inspect} of type #{val.class.name} cannot be assigned to attribute #{attribute_name.inspect} of type #{type.name} (Strict: #{strict.inspect})"
end
end
end
end
end
if default.nil?
initialize_value = nil
elsif default.respond_to?(:call)
initialize_value = default
else
raise Schema::Attribute::Error, "Default values must be callable, like procs, lambdas, or objects that respond to the call method (Attribute: #{attribute_name})"
end
::Attribute::Define.(self, attribute_name, :accessor, check: check, &initialize_value)
attribute = attributes.register(attribute_name, type, strict)
attribute
end
|