ruby / net-imap

Ruby client api for Internet Message Access Protocol
https://ruby.github.io/net-imap
Other
49 stars 25 forks source link

✨ Add Config methods: `#to_h`, `#update`, and `#with` #300

Closed nevans closed 1 week ago

nevans commented 1 week ago

These methods were originally used to implement #load_defaults (to finish #288), and it seems reasonable to add them to the public API.

Unlike SequenceSet (which I want to have a full API to match Set, Range, and Array), I want to be careful in adding any extra public methods to Config. But I think these three are basic enough to be permitted.

#to_h

Returns all config attributes in a hash.

#update

Assigns all of the provided +attrs+ to this config, and returns +self+.

Each key in +attrs+ must match an assignment method on Config.

In other words, #update does the same thing that #initialize does with its kwargs.

#with

Without a block, returns a new config which inherits from self. With a block, yields the new config and returns the block's result.

I originally made #with create a copy (using dup), which meant it was a "sibling" to the receiver, not a child. I did it that way because that's what I wanted for creating the versioned defaults (see #302) and I extracted the method from that code. Also, that's how Data#with works and I had copied some of the rdoc from there.

But when I went back to add the tests, it seemed clear to me that the Principle of Least Surprise would expect #with to create a child config, inheriting from its creator. I had already created the instance method #new for that purpose, but #with is usefully different enough to justify its distinct existence (in my opinion)

nevans commented 1 week ago

I've also implemented some "standard" ruby methods: #==, #eql?, #hash, #deconstruct_keys, #inspect, and #pretty_print. Maybe I'll add those another PR (they aren't properly tested yet).