Class: Koine::Attributes::Attributes

Inherits:
Object
  • Object
show all
Defined in:
lib/koine/attributes/attributes.rb

Instance Method Summary collapse

Constructor Details

#initialize(object, adapters:, options: {}) ⇒ Attributes

Returns a new instance of Attributes.



4
5
6
7
8
9
10
11
12
13
# File 'lib/koine/attributes/attributes.rb', line 4

def initialize(object, adapters:, options: {})
  @object = object
  @adapters = adapters
  @values = {}
  @initializer = { strict: true, freeze: false, initialize: !options[:initializer].nil? }

  if options[:initializer].is_a?(Hash)
    @initializer = @initializer.merge(options[:initializer])
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/koine/attributes/attributes.rb', line 81

def method_missing(method_name, *args)
  unless respond_to?(method_name)
    raise NoMethodError, "Undefined method #{method_name} for attributed object #{@object}"
  end

  method_name = method_name.to_s

  if method_name.to_s =~ /=$/
    attribute = method_name.to_s.delete('=')
    return set(attribute, *args)
  end

  matches = method_name.match(/^with_(.*)$/)
  return with_attribute(matches[1], *args) if matches

  get(method_name)
end

Instance Method Details

#==(other) ⇒ Object



54
55
56
# File 'lib/koine/attributes/attributes.rb', line 54

def ==(other)
  other.to_h == to_h
end

#get(attribute) ⇒ Object



50
51
52
# File 'lib/koine/attributes/attributes.rb', line 50

def get(attribute)
  @values[attribute.to_sym] || adapter_for(attribute).default_value
end

#initialize_values(values = {}) ⇒ Object



15
16
17
18
19
20
21
22
# File 'lib/koine/attributes/attributes.rb', line 15

def initialize_values(values = {})
  if !@initializer[:initialize] && !values.empty?
    raise ArgumentError, "wrong number of arguments (given #{values.length}, expected 0)"
  end

  return unless @initializer[:initialize]
  set_values(values) && @initializer[:freeze] && freeze
end

#respond_to?(method, _include_private = nil) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/koine/attributes/attributes.rb', line 64

def respond_to?(method, _include_private = nil)
  method = method.to_s

  # getter
  return true if has_attribute?(method)

  # {attribute_name}=value
  matches = method.match(/^(.*)=$/)
  return has_attribute?(matches[1]) if matches

  # with_{attribute}(value)
  matches = method.match(/^with_(.*)$/)
  return has_attribute?(matches[1]) if matches

  false
end

#set(attribute, value) ⇒ Object



41
42
43
# File 'lib/koine/attributes/attributes.rb', line 41

def set(attribute, value)
  @values[attribute.to_sym] = adapter_for(attribute).coerce(value)
end

#set_values(values) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/koine/attributes/attributes.rb', line 24

def set_values(values)
  invalid_attributes = []

  if @initializer[:strict]
    attributes = values.keys.map(&:to_sym)
    invalid_attributes = attributes - valid_attributes
  end

  unless invalid_attributes.empty?
    raise ArgumentError, "Invalid attributes (#{invalid_attributes.join(', ')})"
  end

  values.each do |attribute, value|
    set(attribute, value) if has_attribute?(attribute)
  end
end

#to_hObject



58
59
60
61
62
# File 'lib/koine/attributes/attributes.rb', line 58

def to_h
  valid_attributes.map do |name|
    [name.to_sym, @object.send(name)]
  end.to_h
end

#with_attribute(attribute, value) ⇒ Object



45
46
47
48
# File 'lib/koine/attributes/attributes.rb', line 45

def with_attribute(attribute, value)
  new_attributes = to_h.merge(attribute => value)
  @object.class.new(new_attributes)
end