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
|
# File 'lib/smart_init/main.rb', line 14
def initialize_with_hash *attributes
public_readers_filter = -> (el) {
el.is_a?(Hash) && el.keys == [:public_readers]
}
attributes = attributes.map do |el|
if el.is_a?(Hash)
el.map { |k, v| { k => v } }
else
el
end
end.flatten
public_readers = attributes.select(&public_readers_filter)
attributes.delete_if(&public_readers_filter)
required_attrs = attributes.select { |el| el.is_a?(Symbol) }
default_value_attrs = attributes.select { |el| el.is_a?(Hash) }.reduce(Hash.new, :merge) || {}
define_method :initialize do |*parameters|
parameters = [{}] if parameters == []
unless parameters.first.is_a?(Hash)
raise ArgumentError, "invalid input, expected hash of attributes"
end
required_attrs.each do |required_attr|
unless parameters.first.has_key?(required_attr)
raise ArgumentError, "missing required attribute #{required_attr}"
end
end
(required_attrs + default_value_attrs.keys).each do |attribute|
value = if parameters.first.has_key?(attribute)
parameters.first.fetch(attribute)
else
default_value_attrs[attribute]
end
instance_variable_set("@#{attribute}", value)
end
end
instance_eval do
all_readers = (required_attrs + default_value_attrs.keys).compact
attr_reader(*all_readers)
if public_readers.count == 0
all_readers.each do |method_name|
private method_name
end
elsif public_readers.first.fetch(:public_readers).is_a?(Array)
(all_readers - public_readers.first.fetch(:public_readers)).each do |method_name|
private method_name
end
end
end
end
|