Feature #12210
closedAdd IdentitySet class that compares members by identity
Description
This subclass of Set handles a use case that we ran into where we needed to track instances of objects that might compare as equal.
I was surprised that there was not a core way to do this. IdentitySet allows you to do the following (trivial example using strings):
a_str = "a"
s = IdentitySet.new([a_str, a_str, "b", "b"])
p s # => #<IdentitySet: {"a", "b", "b"}>
Files
Updated by duerst (Martin Dürst) over 8 years ago
I think that rather than creating a new class, adding an option on Set.new (e.g. Set.new([a_str, a_str, "b", "b"], compare_by: :identity)) is more Ruby-like.
Updated by shyouhei (Shyouhei Urabe) over 8 years ago
If you want a new class, why not start as a separate gem for it?
Updated by tjwp (Tim Perkins) over 8 years ago
I submitted this as a patch because the std lib already contains one subclass of Set (SortedSet) and a commented-out implementation of another (RestrictedSet).
I don’t expect that this class will change beyond the initial implementation. Following the precedent of SortedSet, I think that including IdentitySet in the std lib improves discoverability over providing it via a gem, which seems like a more heavyweight solution for a simple, useful variation on a Set.
I was surprised that there wasn't already a standard way to do this.
Updated by shyouhei (Shyouhei Urabe) over 8 years ago
- Status changed from Open to Assigned
- Assignee set to knu (Akinori MUSHA)
Updated by knu (Akinori MUSHA) about 8 years ago
- Tracker changed from Misc to Feature
I'd rather add Set#compare_by_identity.
Updated by knu (Akinori MUSHA) about 8 years ago
- Status changed from Assigned to Closed
Applied in changeset r56589.
Add Set#compare_by_identity and Set#compare_by_identity?
- lib/set.rb (Set#compare_by_identity, Set#compare_by_identity?):
New methods. [Feature #12210]
Updated by knu (Akinori MUSHA) about 8 years ago
Note that SortedSet#compare_by_identity is unimplemented when SortedSet uses rbtree.
rbtree.readjust { |a, b| a.object_id <=> b.object_id }
comes pretty close, but rbtree treats string keys specially by storing a copy of each string key given, so it does not work as expected for string keys. There needs some way provided on the rbtree side.