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(*args, &block) 点击切换源代码
定义一个新的 Data
类。
注意: 与 ruby 3.2 的 Data.define
不同, DataLite.define
仅支持作为有效局部变量名称的成员名称。成员名称不能是关键字(例如:next
或 class
)或以大写字母、“@”等开头。
# 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
公共实例方法
==(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
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