Skip to content

Commit

Permalink
🐛💥 Remove accidental Data#attributes method
Browse files Browse the repository at this point in the history
`#attributes` isn't part of the core `Data` API, and it never should've
been added as a public method to our polyfill.

This is a breaking API change, _but only for users on ruby 3.1._

For users on ruby 3.2+, this is _not_ a breaking change.  For newer ruby
versions, `Data#attributes` wasn't defined and this fixes YAML encoding.

Since this only affects ruby 3.1 and this was only recently added (in
v0.5.2), it's unlikely anyone has written code that uses this method.
If they have, they'll need to convert it to `#to_h`.
  • Loading branch information
nevans committed Jan 3, 2025
1 parent 45c6628 commit 44c47c0
Showing 1 changed file with 11 additions and 10 deletions.
21 changes: 11 additions & 10 deletions lib/net/imap/data_lite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ module Net
class IMAP
data_or_object = RUBY_VERSION >= "3.2.0" ? ::Data : Object
class DataLite < data_or_object
def encode_with(coder) coder.map = attributes.transform_keys(&:to_s) end
def encode_with(coder) coder.map = to_h.transform_keys(&:to_s) end
def init_with(coder) initialize(**coder.map.transform_keys(&:to_sym)) end
end

Expand Down Expand Up @@ -159,28 +159,27 @@ def marshal_load(attrs) #{ivars} = #{attrs}; freeze end

##
def members; self.class.members end
def attributes; Hash[members.map {|m| [m, send(m)] }] end
def to_h(&block) attributes.to_h(&block) end
def hash; [self.class, attributes].hash end
def to_h(&block) block ? __to_h__.to_h(&block) : __to_h__ end
def hash; [self.class, __to_h__].hash end
def ==(other) self.class == other.class && to_h == other.to_h end
def eql?(other) self.class == other.class && hash == other.hash end
def deconstruct; attributes.values end
def deconstruct; __to_h__.values end

def deconstruct_keys(keys)
raise TypeError unless keys.is_a?(Array) || keys.nil?
return attributes if keys&.first.nil?
attributes.slice(*keys)
return __to_h__ if keys&.first.nil?
__to_h__.slice(*keys)
end

def with(**kwargs)
return self if kwargs.empty?
self.class.new(**attributes.merge(kwargs))
self.class.new(**__to_h__.merge(kwargs))
end

def inspect
__inspect_guard__(self) do |seen|
return "#<data #{self.class}:...>" if seen
attrs = attributes.map {|kv| "%s=%p" % kv }.join(", ")
attrs = __to_h__.map {|kv| "%s=%p" % kv }.join(", ")
display = ["data", self.class.name, attrs].compact.join(" ")
"#<#{display}>"
end
Expand All @@ -190,7 +189,9 @@ def inspect
private

def initialize_copy(source) super.freeze end
def marshal_dump; attributes end
def marshal_dump; __to_h__ end

def __to_h__; Hash[members.map {|m| [m, send(m)] }] end

# 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
Expand Down

0 comments on commit 44c47c0

Please sign in to comment.