class Net::IMAP::DataLite
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.
Public Class Methods
Source
Source
# 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
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.
Source
Public Instance Methods
Source
# File lib/net/imap/data_lite.rb, line 164 def ==(other) self.class == other.class && to_h == other.to_h end
Source
# 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
Source
# File lib/net/imap/data_lite.rb, line 32 def encode_with(coder) coder.map = to_h.transform_keys(&:to_s) end
Source
# File lib/net/imap/data_lite.rb, line 165 def eql?(other) self.class == other.class && hash == other.hash end
Source
# File lib/net/imap/data_lite.rb, line 33 def init_with(coder) initialize(**coder.map.transform_keys(&:to_sym)) end
Source
# 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
Source
# File lib/net/imap/data_lite.rb, line 162 def to_h(&block) block ? __to_h__.to_h(&block) : __to_h__ end
Source
# 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