class Net::IMAP::DataLite

DataLite 是 ruby 3.2 的 Data 类的临时替代品。 DataLite 被别名为 Net::IMAP::Data,因此使用它的代码在移除时无需更新。

请参阅 ruby 3.2 关于 Data 的文档

在运行 ruby 3.1 时

此类重新实现了 ruby 3.2 的 Data 的 API,并且在几乎所有用例中都应该兼容。 此重新实现将在 net-imap 0.6 版本中删除,届时将不再支持 ruby 3.1。

注意: net-imap 不再支持 3.1 之前的 ruby 版本。

在运行 ruby >= 3.2 时

此类继承自 Data,并且定义 YAML 序列化所需的方法。 当 psych 添加对 Data 的支持时,这将删除。

此类中的一些代码是从 polyfill-data gem 复制或改编的,作者为 Jim Gay 和 Joel Drapper,采用 MIT 许可条款。

常量

ARITY_ERROR
ATTRSET_ERROR
DUP_ERROR
TYPE_ERROR

公共类方法

::[](*args) → instance 点击切换源代码
::[](**kwargs) → instance

使用 ::define 定义的类的构造函数。

::new 的别名

# File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 151
      
define(*args, &block) 点击切换源代码

定义一个新的 Data 类。

注意: 与 ruby 3.2 的 Data.define 不同, DataLite.define 仅支持作为有效局部变量名称的成员名称。成员名称不能是关键字(例如:nextclass)或以大写字母、“@”等开头。

# 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 点击切换源代码
new(**kwargs) → instance

使用 ::define 定义的类的构造函数。

别名为 ::[]

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

公共实例方法

==(other) 点击切换源代码
# 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() 点击切换源代码
# 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() 点击切换源代码
# File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 167
def deconstruct; attributes.values                               end
deconstruct_keys(keys) 点击切换源代码
# 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) 点击切换源代码
# 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) 点击切换源代码
# 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() 点击切换源代码
# File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 164
def hash;        [self.class, attributes].hash                   end
init_with(coder) 点击切换源代码
# 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() 点击切换源代码
# 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
也别名为: to_s
members() 点击切换源代码
# File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 161
def members;     self.class.members                              end
to_h(&block) 点击切换源代码
# 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()
别名为: inspect
with(**kwargs) 点击切换源代码
# 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

私有实例方法

__inspect_guard__(obj) { |true| ... } 点击切换源代码

如果 obj 已经出现过则返回 true,如果未出现过则返回 false。 在块内部将 obj 标记为已出现,因此循环引用不会递归触发 SystemStackError(堆栈级别太深)。

Data 对象内部进行循环引用应该非常不常见,但为了完整性,我们将支持它们。

# 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) 点击切换源代码
调用父类方法
# File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 192
def initialize_copy(source) super.freeze end
marshal_dump() 点击切换源代码
# File net-imap-0.5.4/lib/net/imap/data_lite.rb, line 193
def marshal_dump; attributes end