Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hash compare by identity #8451

Merged
merged 5 commits into from
Nov 8, 2019

Conversation

asterite
Copy link
Member

@asterite asterite commented Nov 7, 2019

Implements #8329

Has a commit from #8450 but I can later rebase on top of master, or just rewrite git history.

src/hash.cr Outdated

private def entry_matches?(entry, key)
entry_key = entry.key
if @compare_by_identity && entry_key.responds_to?(:object_id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if @compare_by_identity is true and entry responds to object_id but entry_key doesn't? Shouldn't that also return false even if entry_key == key?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. If entry_key is an int you still want ints to compare the same way.

I also thought about raising a compile-time error when using compare_by_identity on a hash where keys don't respond to object_id, but it involved a chunk of macro code. Would something like that be better?

In general, I wouldn't worry too much about this. If you use compare_by_identity you generally know what you are doing and you'll be already working with reference types, or reference-like types. But we can try adding the macro check.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what's the best semantics here. But I'd try to be consistent.

Currently, when comparing by identity the behaviour for differing answers to responds_to?(:object_id) is inconsistent:

  • when entry_key.responds_to?(:object_id) && !key.responds_to?(:object_id) the result is false
  • when !entry_key.responds_to?(:object_id) && key.responds_to?(:object_id) the result is entry_key == key

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, I'll at least make it consistent

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Let me know what you think.

@asterite asterite force-pushed the hash-compare-by-identity branch from 1dc88ec to 860067c Compare November 7, 2019 18:48
Copy link
Member

@bcardiff bcardiff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't dup and clone preserve the compare_by_identity?

@asterite
Copy link
Member Author

asterite commented Nov 7, 2019

Shouldn't dup and clone preserve the compare_by_identity?

Great catch! Done

@asterite asterite added this to the 0.32.0 milestone Nov 8, 2019
@asterite asterite merged commit 8459700 into crystal-lang:master Nov 8, 2019
@asterite asterite deleted the hash-compare-by-identity branch November 8, 2019 12:09
@bew
Copy link
Contributor

bew commented Dec 11, 2019

Is it intentional to not have a way to switch back to "compare by hash" ?

@straight-shoota
Copy link
Member

Switching back an forth on the same instance would be confusing. compare_by_identity should be configured only once and prior to any usage of the hash. Ideally, that's in the constructor and I think we should actually make it a constructor argument (see discussion in #8329).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants