Class: Data

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

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**kwargs) ⇒ Data

Returns a new instance of Data.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/data.rb', line 59

def initialize(**kwargs)
  kwargs_size = kwargs.size
  members_size = members.size

  if kwargs_size > members_size
    extras = kwargs.reject{|k, _v| members.include?(k) }.keys
    raise ArgumentError, "unknown arguments #{extras.join(', ')}"
  elsif kwargs_size < members_size
    missing = members.select {|k, _v| !kwargs.include?(k) }
    raise ArgumentError, "missing arguments #{missing.map{ ":#{_1}" }.join(', ')}"
  end

  @attributes = Hash[members.map {|m| [m,kwargs[m]] }]
end

Class Attribute Details

.membersObject (readonly)

Returns the value of attribute members.



12
13
14
# File 'lib/data.rb', line 12

def members
  @members
end

Class Method Details

.define(*args, &block) ⇒ Object

Raises:

  • (ArgumentError)


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
# File 'lib/data.rb', line 15

def self.define(*args, &block)
  raise ArgumentError if args.any?(/=/)
  klass = ::Class.new(self, &block)

  if args.first.is_a?(String)
    name = args.shift
    Data.const_set(name, klass)
  end

  klass.instance_variable_set(:@members, args)

  klass.define_singleton_method(:new) do |*new_args, **new_kwargs, &block|
    init_kwargs = if new_args.any?
      raise ArgumentError, "unknown arguments #{new_args[members.size..].join(', ')}" if new_args.size > members.size
      Hash[members.take(new_args.size).zip(new_args)]
    else
      new_kwargs
    end

    self.allocate.tap do |instance|
      instance.send(:initialize, **init_kwargs, &block)
    end.freeze
  end
  class << klass
    alias_method :[], :new
    undef_method :define
  end

  args.map do |arg|
    if klass.method_defined?(arg)
      raise ArgumentError, "duplicate member #{arg}"
    end
    klass.define_method(arg) do
      @attributes[arg]
    end
  end

  klass
end

Instance Method Details

#==(other) ⇒ Object



97
98
99
# File 'lib/data.rb', line 97

def ==(other)
  self.class == other.class && to_h == other.to_h
end

#deconstructObject



74
75
76
# File 'lib/data.rb', line 74

def deconstruct
  @attributes.values
end

#deconstruct_keys(array) ⇒ Object

Raises:

  • (TypeError)


78
79
80
81
82
83
# File 'lib/data.rb', line 78

def deconstruct_keys(array)
  raise TypeError unless array.is_a?(Array) || array.nil?
  return @attributes if array&.first.nil?

  @attributes.slice(*array)
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


93
94
95
# File 'lib/data.rb', line 93

def eql?(other)
  self.class == other.class && hash == other.hash
end

#hashObject



89
90
91
# File 'lib/data.rb', line 89

def hash
  to_h.hash
end

#inspectObject Also known as: to_s



101
102
103
104
105
106
107
108
# File 'lib/data.rb', line 101

def inspect
  name = ["data", self.class.name].compact.join(" ")
  attribute_markers = @attributes.map do |key, value|
    insect_key = key.to_s.start_with?("@") ? ":#{key}" : key
    "#{insect_key}=#{value}"
  end
  %(#<#{name} #{attribute_markers.join(", ")}>)
end

#membersObject



55
56
57
# File 'lib/data.rb', line 55

def members
  self.class.members
end

#to_h(&block) ⇒ Object



85
86
87
# File 'lib/data.rb', line 85

def to_h(&block)
  @attributes.to_h(&block)
end

#with(**kwargs) ⇒ Object



111
112
113
114
115
# File 'lib/data.rb', line 111

def with(**kwargs)
  return self if kwargs.empty?

  self.class.new(**@attributes.merge(kwargs))
end