Class: Struct
Overview
Pure Ruby re-implementation of Struct to ensure cross-Ruby functionality where needed (e.g. Opal)
Struct class object instances store members in @members Array and member values in @member_values Hash
API perfectly matches that of Native Ruby built-in Struct.
Native Ruby built-in Struct implementation is aliased as NativeStruct
Class Method Summary collapse
Instance Method Summary collapse
- #==(other) ⇒ Object
- #[](attribute) ⇒ Object
- #[]=(attribute, value) ⇒ Object
- #dig(*args) ⇒ Object
-
#each(&block) ⇒ Object
Iterates through each value.
-
#each_pair(&block) ⇒ Object
Iterates through each member value pair.
- #eql?(other) ⇒ Boolean
-
#hash ⇒ Object
Return compound hash value consisting of Struct class hash and all indexed value hashes.
-
#members ⇒ Object
Returns member symbols (strings in Opal) representing Struct attribute names.
-
#select(&block) ⇒ Object
Selects values with block (only value is passed in as block arg).
- #size ⇒ Object (also: #length)
-
#to_a ⇒ Object
Returns values Array (no member keys).
-
#to_h ⇒ Object
Returns member values Hash (includes member keys).
-
#to_s ⇒ Object
(also: #inspect)
Prints Struct member values including class name if set.
Class Method Details
.__new__ ⇒ Object
37 |
# File 'lib/pure-struct.rb', line 37 alias __new__ new |
.new(class_name_or_attribute, *attributes, keyword_init: false) ⇒ Object
40 41 42 43 44 45 46 47 |
# File 'lib/pure-struct.rb', line 40 def new(class_name_or_attribute, *attributes, keyword_init: false) raise 'Arguments cannot be nil' if ARG_VALIDATION[class_name_or_attribute, *attributes] class_name = CLASS_NAME_EXTRACTION[class_name_or_attribute] attributes.unshift(class_name_or_attribute) if class_name.nil? attributes = attributes.map(&:to_sym) struct_class = Class.new(self, &CLASS_DEFINITION_FOR_ATTRIBUTES[attributes, keyword_init]) class_name.nil? ? struct_class : const_set(class_name, struct_class) end |
Instance Method Details
#==(other) ⇒ Object
189 190 191 192 193 |
# File 'lib/pure-struct.rb', line 189 def ==(other) other = coerce(other).first if respond_to?(:coerce, true) other.kind_of?(self.class) && @members.all? { |key| (self[key].equal?(self) && other[key].equal?(self)) || self[key] == other[key] } end |
#[](attribute) ⇒ Object
120 121 122 123 124 |
# File 'lib/pure-struct.rb', line 120 def [](attribute) normalized_attribute = attribute.to_sym raise NameError, "no member #{attribute} in struct" unless @members.include?(normalized_attribute) @member_values[normalized_attribute] end |
#[]=(attribute, value) ⇒ Object
114 115 116 117 118 |
# File 'lib/pure-struct.rb', line 114 def []=(attribute, value) normalized_attribute = attribute.to_sym raise NameError, "no member #{attribute} in struct" unless @members.include?(normalized_attribute) @member_values[normalized_attribute] = value end |
#dig(*args) ⇒ Object
175 176 177 |
# File 'lib/pure-struct.rb', line 175 def dig(*args) @member_values.dig(*args) end |
#each(&block) ⇒ Object
Iterates through each value
127 128 129 |
# File 'lib/pure-struct.rb', line 127 def each(&block) to_a.each(&block) end |
#each_pair(&block) ⇒ Object
Iterates through each member value pair
132 133 134 |
# File 'lib/pure-struct.rb', line 132 def each_pair(&block) @member_values.each_pair(&block) end |
#eql?(other) ⇒ Boolean
184 185 186 187 |
# File 'lib/pure-struct.rb', line 184 def eql?(other) instance_of?(other.class) && @members.all? { |key| (self[key].equal?(self) && other[key].equal?(self)) || self[key].eql?(other[key]) } end |
#hash ⇒ Object
Return compound hash value consisting of Struct class hash and all indexed value hashes
Opal doesn’t implement hash as Integer everywhere, returning strings as themselves, so this returns a String in Opal as a safe common denominator for all object types.
199 200 201 202 203 204 205 206 207 208 |
# File 'lib/pure-struct.rb', line 199 def hash return __hash__opal__ if RUBY_ENGINE == 'opal' class_hash = self.class.hash indexed_values = to_a.each_with_index value_hashes = indexed_values.map do |value, i| value_hash = value.equal?(self) ? class_hash : value.hash i+1 * value_hash end class_hash + value_hashes.sum end |
#members ⇒ Object
Returns member symbols (strings in Opal) representing Struct attribute names
110 111 112 |
# File 'lib/pure-struct.rb', line 110 def members (@members ||= self.class.class_variable_get(:@@attributes)).clone end |
#select(&block) ⇒ Object
Selects values with block (only value is passed in as block arg)
180 181 182 |
# File 'lib/pure-struct.rb', line 180 def select(&block) to_a.select(&block) end |
#size ⇒ Object Also known as: length
170 171 172 |
# File 'lib/pure-struct.rb', line 170 def size @members.size end |
#to_a ⇒ Object
Returns values Array (no member keys)
142 143 144 |
# File 'lib/pure-struct.rb', line 142 def to_a @member_values.values end |
#to_h ⇒ Object
Returns member values Hash (includes member keys)
137 138 139 |
# File 'lib/pure-struct.rb', line 137 def to_h @member_values.clone end |
#to_s ⇒ Object Also known as: inspect
Prints Struct member values including class name if set
#inspect does the same thing
__inspect__ aliases the original Object inspect implementation
155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/pure-struct.rb', line 155 def to_s member_values_string = @member_values.map do |member, value| if value.equal?(self) value_class_string = self.class.send(:__inspect__).split.first value_string = "#<struct #{value_class_string}:...>" else value_string = value.inspect end "#{member}=#{value_string}" end.join(', ') class_name_string = "#{self.class.name} " unless self.class.name.nil? "#<struct #{class_name_string}#{member_values_string}>" end |