Class: JSI::Util::Private::AttrStruct Private
- Inherits:
-
Object
- Object
- JSI::Util::Private::AttrStruct
- Includes:
- FingerprintHash
- Defined in:
- lib/jsi/util/private/attr_struct.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
like a Struct, but stores all the attributes in one @attributes Hash, instead of individual instance variables for each attribute. this tends to be easier to work with and more flexible. keys which are symbols are converted to strings.
Defined Under Namespace
Classes: AttrStructError, UndefinedAttributeKey
Class Method Summary collapse
-
.attribute_keys ⇒ Set<String>
private
the attribute keys defined for this class.
-
.convert_key(key) ⇒ Object
private
returns a frozen string, given a string or symbol.
-
.subclass(*attribute_keys) ⇒ Object
(also: [])
private
creates a AttrStruct subclass with the given attribute keys.
Instance Method Summary collapse
- #[](key) ⇒ Object private
- #[]=(key, value) ⇒ Object private
-
#class_attribute_keys ⇒ Set<String>
private
the attribute keys defined for this class.
- #freeze ⇒ Object private
-
#initialize(attributes = {}) ⇒ AttrStruct
constructor
private
A new instance of AttrStruct.
- #inspect ⇒ String private
-
#jsi_fingerprint ⇒ Object
private
see FingerprintHash.
-
#pretty_print(q)
private
pretty-prints a representation of self to the given printer.
- #to_s ⇒ Object private
Methods included from FingerprintHash
Constructor Details
#initialize(attributes = {}) ⇒ AttrStruct
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.
Returns a new instance of AttrStruct.
68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/jsi/util/private/attr_struct.rb', line 68 def initialize(attributes = {}) unless attributes.respond_to?(:to_hash) raise(TypeError, "expected attributes to be a Hash; got: #{attributes.inspect}") end @attributes = {} attributes.to_hash.each do |k, v| @attributes[self.class.convert_key(k)] = v end bad = @attributes.keys.reject { |k| class_attribute_keys.include?(k) } unless bad.empty? raise UndefinedAttributeKey, "undefined attribute keys: #{bad.map(&:inspect).join(', ')}" end end |
Class Method Details
.attribute_keys ⇒ Set<String>
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.
the attribute keys defined for this class
54 55 56 57 |
# File 'lib/jsi/util/private/attr_struct.rb', line 54 def attribute_keys # empty for AttrStruct itself; redefined on each subclass Util::Private::EMPTY_SET end |
.convert_key(key) ⇒ 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.
returns a frozen string, given a string or symbol. returns anything else as-is for the caller to handle.
62 63 64 65 |
# File 'lib/jsi/util/private/attr_struct.rb', line 62 def convert_key(key) # TODO use Symbol#name when available on supported rubies key.is_a?(Symbol) ? key.to_s.freeze : key.frozen? ? key : key.is_a?(String) ? key.dup.freeze : key end |
.subclass(*attribute_keys) ⇒ Object Also known as: []
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.
creates a AttrStruct subclass with the given attribute keys.
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 |
# File 'lib/jsi/util/private/attr_struct.rb', line 18 def subclass(*attribute_keys) bad_type = attribute_keys.reject { |key| key.respond_to?(:to_str) || key.is_a?(Symbol) } unless bad_type.empty? raise(ArgumentError, "attribute keys must be String or Symbol; got keys: #{bad_type.map(&:inspect).join(', ')}") end attribute_keys = attribute_keys.map { |key| convert_key(key) } bad_name = attribute_keys.reject { |key| Util::Private.ok_ruby_method_name?(key) } unless bad_name.empty? raise(ArgumentError, "attribute keys must be valid ruby method names; got keys: #{bad_name.map(&:inspect).join(', ')}") end all_attribute_keys = (self.attribute_keys + attribute_keys).freeze Class.new(self).tap do |klass| klass.define_singleton_method(:attribute_keys) { all_attribute_keys } attribute_keys.each do |attribute_key| # reader klass.send(:define_method, attribute_key) do @attributes[attribute_key] end # writer klass.send(:define_method, "#{attribute_key}=") do |value| @attributes[attribute_key] = value end end end end |
Instance Method Details
#[](key) ⇒ 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.
82 83 84 |
# File 'lib/jsi/util/private/attr_struct.rb', line 82 def [](key) @attributes[key.is_a?(Symbol) ? key.to_s : key] end |
#[]=(key, value) ⇒ 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.
86 87 88 89 90 91 92 |
# File 'lib/jsi/util/private/attr_struct.rb', line 86 def []=(key, value) key = self.class.convert_key(key) unless class_attribute_keys.include?(key) raise UndefinedAttributeKey, "undefined attribute key: #{key.inspect}" end @attributes[key] = value end |
#class_attribute_keys ⇒ Set<String>
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.
the attribute keys defined for this class
123 124 125 |
# File 'lib/jsi/util/private/attr_struct.rb', line 123 def class_attribute_keys self.class.attribute_keys end |
#freeze ⇒ 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.
127 128 129 130 |
# File 'lib/jsi/util/private/attr_struct.rb', line 127 def freeze @attributes.freeze super end |
#inspect ⇒ String
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.
95 96 97 |
# File 'lib/jsi/util/private/attr_struct.rb', line 95 def inspect -"\#<#{self.class.name}#{@attributes.map { |k, v| " #{k}: #{v.inspect}" }.join(',')}>" end |
#jsi_fingerprint ⇒ 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.
see FingerprintHash
136 137 138 |
# File 'lib/jsi/util/private/attr_struct.rb', line 136 def jsi_fingerprint {class: self.class, attributes: @attributes}.freeze end |
#pretty_print(q)
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.
This method returns an undefined value.
pretty-prints a representation of self to the given printer
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/jsi/util/private/attr_struct.rb', line 105 def pretty_print(q) q.text '#<' q.text self.class.name q.group(2) { q.breakable(' ') if !@attributes.empty? q.seplist(@attributes, nil, :each_pair) { |k, v| q.group { q.text k q.text ': ' q.pp v } } } q.breakable('') if !@attributes.empty? q.text '>' end |
#to_s ⇒ 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.
99 100 101 |
# File 'lib/jsi/util/private/attr_struct.rb', line 99 def to_s inspect end |