Class: Net::IMAP::DataLite
- Inherits:
-
Object
- Object
- Net::IMAP::DataLite
- Defined in:
- lib/net/imap/data_lite.rb,
lib/net/imap/data_lite.rb
Overview
DataLite is a temporary substitute for ruby 3.2’s Data class. DataLite is aliased as Net::IMAP::Data, so that code using it won’t need to be updated when it is removed.
See ruby 3.2’s documentation for Data.
- When running ruby 3.1
-
This class reimplements the API for ruby 3.2’s
Data, and should be compatible for nearly all use-cases. This reimplementation will be removed innet-imap0.6, when support for ruby 3.1 is dropped.NOTE:
net-imapno longer supports ruby versions prior to 3.1. - When running ruby >= 3.2
-
This class inherits from
Dataand only defines the methods needed for YAML serialization. This will be dropped whenpsychadds support forData.
Some of the code in this class was copied or adapted from the polyfill-data gem, by Jim Gay and Joel Drapper, under the MIT license terms.
Class Method Summary collapse
-
.define(*args, &block) ⇒ Object
Defines a new Data class.
Instance Method Summary collapse
- #==(other) ⇒ Object
- #deconstruct ⇒ Object
- #deconstruct_keys(keys) ⇒ Object
- #encode_with(coder) ⇒ Object
- #eql?(other) ⇒ Boolean
- #hash ⇒ Object
- #init_with(coder) ⇒ Object
- #inspect ⇒ Object (also: #to_s)
- #members ⇒ Object
- #to_h(&block) ⇒ Object
- #with(**kwargs) ⇒ Object
Class Method Details
.define(*args, &block) ⇒ Object
Defines a new Data class.
NOTE: Unlike ruby 3.2’s Data.define, DataLite.define only supports member names which are valid local variable names. Member names can’t be keywords (e.g: next or class) or start with capital letters, “@”, etc.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/net/imap/data_lite.rb', line 81 def self.define(*args, &block) members = args.each_with_object({}) do |arg, members| arg = arg.to_str unless arg in Symbol | String if arg.respond_to?(:to_str) arg = arg.to_sym if arg in String arg in Symbol or raise TypeError, TYPE_ERROR % [arg] arg in %r{=} and raise ArgumentError, ATTRSET_ERROR % [arg] members.key?(arg) and raise ArgumentError, DUP_ERROR % [arg] members[arg] = true end members = members.keys.freeze klass = ::Class.new(self) klass.singleton_class.undef_method :define klass.define_singleton_method(:members) { members } def klass.new(*args, **kwargs, &block) if kwargs.size.positive? if args.size.positive? raise ArgumentError, ARITY_ERROR % [args.size, 0] end elsif members.size < args.size expected = members.size.zero? ? 0 : 0..members.size raise ArgumentError, ARITY_ERROR % [args.size, expected] else kwargs = Hash[members.take(args.size).zip(args)] end allocate.tap do |instance| instance.__send__(:initialize, **kwargs, &block) end.freeze end klass.singleton_class.alias_method :[], :new klass.attr_reader(*members) # Dynamically defined initializer methods are in an included module, # rather than directly on DataLite (like in ruby 3.2+): # * simpler to handle required kwarg ArgumentErrors # * easier to ensure consistent ivar assignment order (object shape) # * faster than instance_variable_set klass.include(Module.new do if members.any? kwargs = members.map{"#{_1.name}:"}.join(", ") params = members.map(&:name).join(", ") ivars = members.map{"@#{_1.name}"}.join(", ") attrs = members.map{"attrs[:#{_1.name}]"}.join(", ") module_eval <<~RUBY, __FILE__, __LINE__ + 1 protected def initialize(#{kwargs}) #{ivars} = #{params}; freeze end def marshal_load(attrs) #{ivars} = #{attrs}; freeze end RUBY end end) klass.module_eval do _1.module_eval(&block) end if block_given? klass end |
Instance Method Details
#==(other) ⇒ Object
164 |
# File 'lib/net/imap/data_lite.rb', line 164 def ==(other) self.class == other.class && to_h == other.to_h end |
#deconstruct ⇒ Object
166 |
# File 'lib/net/imap/data_lite.rb', line 166 def deconstruct; __to_h__.values end |
#deconstruct_keys(keys) ⇒ Object
168 169 170 171 172 |
# File 'lib/net/imap/data_lite.rb', line 168 def deconstruct_keys(keys) raise TypeError unless keys.is_a?(Array) || keys.nil? return __to_h__ if keys&.first.nil? __to_h__.slice(*keys) end |
#encode_with(coder) ⇒ Object
32 |
# File 'lib/net/imap/data_lite.rb', line 32 def encode_with(coder) coder.map = to_h.transform_keys(&:to_s) end |
#eql?(other) ⇒ Boolean
165 |
# File 'lib/net/imap/data_lite.rb', line 165 def eql?(other) self.class == other.class && hash == other.hash end |
#hash ⇒ Object
163 |
# File 'lib/net/imap/data_lite.rb', line 163 def hash; [self.class, __to_h__].hash end |
#init_with(coder) ⇒ Object
33 |
# File 'lib/net/imap/data_lite.rb', line 33 def init_with(coder) initialize(**coder.map.transform_keys(&:to_sym)) end |
#inspect ⇒ Object Also known as: to_s
179 180 181 182 183 184 185 186 |
# File 'lib/net/imap/data_lite.rb', line 179 def inspect __inspect_guard__(self) do |seen| return "#<data #{self.class}:...>" if seen attrs = __to_h__.map {|kv| "%s=%p" % kv }.join(", ") display = ["data", self.class.name, attrs].compact.join(" ") "#<#{display}>" end end |
#members ⇒ Object
161 |
# File 'lib/net/imap/data_lite.rb', line 161 def members; self.class.members end |
#to_h(&block) ⇒ Object
162 |
# File 'lib/net/imap/data_lite.rb', line 162 def to_h(&block) block ? __to_h__.to_h(&block) : __to_h__ end |
#with(**kwargs) ⇒ Object
174 175 176 177 |
# File 'lib/net/imap/data_lite.rb', line 174 def with(**kwargs) return self if kwargs.empty? self.class.new(**__to_h__.merge(kwargs)) end |