Class: Fear::Struct
- Inherits:
-
Object
- Object
- Fear::Struct
- Defined in:
- lib/fear/struct.rb
Overview
Structs are like regular classes and good for modeling immutable data.
A minimal struct requires just a list of attributes:
User = Fear::Struct.with_attributes(:id, :email, :admin)
john = User.new(id: 2, email: '[email protected]', admin: false)
john.email #=> '[email protected]'
Instead of ‘.with_attributes` factory method you can use classic inheritance:
class User < Fear::Struct
attribute :id
attribute :email
attribute :admin
end
Since structs are immutable, you are not allowed to reassign their attributes
john.email = ''[email protected]'' #=> raises NoMethodError
Two structs of the same type with the same attributes are equal
john1 = User.new(id: 2, email: '[email protected]', admin: false)
john2 = User.new(id: 2, admin: false, email: '[email protected]')
john1 == john2 #=> true
You can create a shallow copy of a Struct
by using copy method optionally changing its attributes.
john = User.new(id: 2, email: '[email protected]', admin: false)
admin_john = john.copy(admin: true)
john.admin #=> false
admin_john.admin #=> true
Class Method Summary collapse
-
.attribute(name) ⇒ Symbol
Defines attribute.
-
.attributes ⇒ <Symbol>
Members of this struct.
- .inherited(base) ⇒ Object private
-
.with_attributes(*members, &block) ⇒ Fear::Struct
Creates new struct with given attributes.
Instance Method Summary collapse
- #==(other) ⇒ Boolean
-
#copy(**attributes) ⇒ Object
Creates a shallow copy of this struct optionally changing the attributes arguments.
- #deconstruct_keys(keys) ⇒ Hash
-
#initialize(**attributes) ⇒ Struct
constructor
A new instance of Struct.
- #inspect ⇒ String (also: #to_s)
-
#members ⇒ <Symbol>
Returns the struct attributes as an array of symbols.
-
#to_a ⇒ Array
Returns the values for this struct as an Array.
- #to_h(&block) ⇒ Object
Constructor Details
#initialize(**attributes) ⇒ Struct
Returns a new instance of Struct.
101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/fear/struct.rb', line 101 def initialize(**attributes) _check_missing_attributes!(attributes) _check_unknown_attributes!(attributes) @values = members.each_with_object([]) do |name, values| attributes.fetch(name).tap do |value| _set_attribute(name, value) values << value end end end |
Class Method Details
.attribute(name) ⇒ Symbol
Defines attribute
64 65 66 67 68 69 |
# File 'lib/fear/struct.rb', line 64 def attribute(name) name.to_sym.tap do |symbolized_name| @attributes << symbolized_name attr_reader symbolized_name end end |
.attributes ⇒ <Symbol>
Members of this struct
74 75 76 |
# File 'lib/fear/struct.rb', line 74 def attributes @attributes.dup end |
.inherited(base) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
49 50 51 |
# File 'lib/fear/struct.rb', line 49 def inherited(base) base.instance_variable_set(:@attributes, attributes) end |
.with_attributes(*members, &block) ⇒ Fear::Struct
Creates new struct with given attributes
89 90 91 92 93 94 95 96 97 |
# File 'lib/fear/struct.rb', line 89 def with_attributes(*members, &block) members = members block = block Class.new(self) do members.each { |member| attribute(member) } class_eval(&block) if block end end |
Instance Method Details
#==(other) ⇒ Boolean
179 180 181 |
# File 'lib/fear/struct.rb', line 179 def ==(other) other.is_a?(other.class) && to_h == other.to_h end |
#copy(**attributes) ⇒ Object
Creates a shallow copy of this struct optionally changing the attributes arguments.
123 124 125 |
# File 'lib/fear/struct.rb', line 123 def copy(**attributes) self.class.new(**to_h.merge(attributes)) end |
#deconstruct_keys(keys) ⇒ Hash
229 230 231 232 233 234 235 |
# File 'lib/fear/struct.rb', line 229 def deconstruct_keys(keys) if keys to_h.slice(*(self.class.attributes & keys)) else to_h end end |
#inspect ⇒ String Also known as: to_s
193 194 195 196 197 |
# File 'lib/fear/struct.rb', line 193 def inspect attributes = to_h.map { |key, value| "#{key}=#{value.inspect}" }.join(", ") format(INSPECT_TEMPLATE, class_name: self.class.name, attributes: attributes) end |
#members ⇒ <Symbol>
Returns the struct attributes as an array of symbols
135 136 137 |
# File 'lib/fear/struct.rb', line 135 def members self.class.attributes end |
#to_a ⇒ Array
Returns the values for this struct as an Array.
147 148 149 |
# File 'lib/fear/struct.rb', line 147 def to_a @values.dup end |
#to_h ⇒ {Symbol => any} #to_h {|pair| ... } ⇒ {Symbol => any}
168 169 170 171 172 173 174 175 |
# File 'lib/fear/struct.rb', line 168 def to_h(&block) pairs = members.zip(@values) if block_given? Hash[pairs.map(&block)] else Hash[pairs] end end |