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

Struct#== should ignore generic type arguments #10311

Open
straight-shoota opened this issue Jan 27, 2021 · 1 comment · May be fixed by #10456
Open

Struct#== should ignore generic type arguments #10311

straight-shoota opened this issue Jan 27, 2021 · 1 comment · May be fixed by #10456
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib

Comments

@straight-shoota
Copy link
Member

For a generic struct Foo(T) equality with another generic instance type like Foo(U)#==(other : Foo(V)) with different T and V always returns false. The reason is the type restriction to self in Struct#== which strictly compares generic type arguments.

There might be cases where this behaviour is correct, but usually the equality operator is not strict about types (1 == 1.0 is true) and structs should be expected to have equality defined by actual values. Even if generic type arguments mismatch: For example 1..1 == 1.0..1.0 should be true (the specific example with Range is detailed in #10309).

The solution would be to replace the type restriction to self (which is the generic instance type) with a broader restriction to the generic class type.

This can be implemented with is_a?({{ @type.name(generic_args: false) }}).

However, this doesn't work for private types because of #4269:

module Foo
  private struct Bar
  end

  p! Bar.new == Bar.new # Error: private constant Foo::Bar referenced
end

A workaround could be to use self for non-generic types. That would leave only private generic types to fail, which is probably very rare. It's still hacky, though.

I think this serves as an encouragement to lift restricions on private type references as proposed in #4269 (comment).

@straight-shoota straight-shoota added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib labels Jan 27, 2021
@straight-shoota straight-shoota linked a pull request Feb 28, 2021 that will close this issue
@straight-shoota
Copy link
Member Author

This recent article by @asterite has reminded me of this issue: https://dev.to/asterite/why-i-love-ruby-part-1-20h2

The basic claim is that it's great to have sensible defaults for basic features such as equality comparison.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant