class Net::IMAP::DataLite - net-imap: Ruby Standard Library Documentation

# 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 in `net-imap` 0.6, when support for ruby 3.1 is dropped.

  NOTE: `net-imap` no longer supports ruby versions prior to 3.1.

When running ruby >= 3.2

  This class inherits from `Data` and only defines the methods needed for YAML serialization. This will be dropped when `psych` adds support for `Data`.

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.

### Constants

ARITY_ERROR
ATTRSET_ERROR
DUP_ERROR
TYPE_ERROR

### Public Class Methods

::[](*args) → instance click to toggle source
::[](**kwargs) → instance

Constuctor for classes defined with `::define`.

Alias for `::new`

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 151

define(*args, &block) click to toggle source

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.

    # File net-imap-0.5.4/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

new(*args) → instance click to toggle source
new(**kwargs) → instance

Constuctor for classes defined with `::define`.

Aliased as `::[]`.

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 141

### Public Instance Methods

==(other) click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 165
    def ==(other)    self.class == other.class && to_h == other.to_h end

attributes() click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 162
    def attributes;  Hash[members.map {|m| [m, send(m)] }]           end

deconstruct() click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 167
    def deconstruct; attributes.values                               end

deconstruct_keys(keys) click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 169
    def deconstruct_keys(keys)
      raise TypeError unless keys.is_a?(Array) || keys.nil?
      return attributes if keys&.first.nil?
      attributes.slice(*keys)
    end

encode_with(coder) click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 32
    def encode_with(coder) coder.map = attributes.transform_keys(&:to_s) end

eql?(other) click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 166
    def eql?(other)  self.class == other.class && hash == other.hash end

hash() click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 164
    def hash;        [self.class, attributes].hash                   end

init_with(coder) click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 33
    def init_with(coder) initialize(**coder.map.transform_keys(&:to_sym)) end

inspect() click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 180
    def inspect
      __inspect_guard__(self) do |seen|
        return "#<data #{self.class}:...>" if seen
        attrs = attributes.map {|kv| "%s=%p" % kv }.join(", ")
        display = ["data", self.class.name, attrs].compact.join(" ")
        "#<#{display}>"
      end
    end

Also aliased as: to_s
members() click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 161
    def members;     self.class.members                              end

to_h(&block) click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 163
    def to_h(&block) attributes.to_h(&block)                         end

to_s()
Alias for: inspect
with(**kwargs) click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 175
    def with(**kwargs)
      return self if kwargs.empty?
      self.class.new(**attributes.merge(kwargs))
    end

### Private Instance Methods

__inspect_guard__(obj) { |true| ... } click to toggle source

Yields `true` if `obj` has been seen already, `false` if it hasn’t. Marks `obj` as seen inside the block, so circuler references don’t recursively trigger a SystemStackError (stack level too deep).

Making circular references inside a `Data` object should be very uncommon, but we’ll support them for the sake of completeness.

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 201
    def __inspect_guard__(obj)
      preexisting = Thread.current[:__net_imap_data__inspect__]
      Thread.current[:__net_imap_data__inspect__] ||= {}.compare_by_identity
      inspect_guard = Thread.current[:__net_imap_data__inspect__]
      if inspect_guard.include?(obj)
        yield true
      else
        begin
          inspect_guard[obj] = true
          yield false
        ensure
          inspect_guard.delete(obj)
        end
      end
    ensure
      unless preexisting.equal?(inspect_guard)
        Thread.current[:__net_imap_data__inspect__] = preexisting
      end
    end

initialize_copy(source) click to toggle source
Calls superclass method

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 192
    def initialize_copy(source) super.freeze end

marshal_dump() click to toggle source

    # File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 193
    def marshal_dump; attributes end