dry-rb / dry-logic

Predicate logic with rule composition

Home Page:https://dry-rb.org/gems/dry-logic/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`Predicate#eql?(left, right)` breaks lots of conventions

casperisfine opened this issue · comments

Describe the bug

It's not my code breaking so I'm just describing it from the outside:

~/gems/dry-logic-1.1.0/lib/dry/logic/predicates.rb:181:in `eql?': wrong number of arguments (given 1, expected 2) (ArgumentError)
from /usr/local/ruby/lib/ruby/3.0.0/set.rb:247:in `include?'
from /~/gems/tapioca-0.5.4/lib/tapioca/compilers/dsl/base.rb:33:in `handles?'

Just based on the error and backtrace, I believe defining eql? is a bad idea because it's a method used by lots of low-level code, for checking identity "hash equality".

I believe it would be best if that method was renamed (or at least behaved like Object#eql? when called with a single argument).

To add more context on this issue, the failure was in the Tapioca gem that I co-maintain. The gem does a lot of runtime introspection on constants in memory, so ends up running into these kinds of cases.

For the time being, we've worked around the problem by using compare_by_identity! but dry-logic would be a much better community member if it didn't break common expectations like eql?.

This, along with renaming Predicates.respond_to?, should go into 2.0.0 release

@casperisfine @paracycle thanks for reporting this and explaining the context. I'm responsible for this unfortunate name and even though I was perfectly aware of the fact that it overrides a core method, I naively thought to myself "it shouldn't cause issues in case of a module, right?". Since nobody complained for years, I never reconsidered this.

I'm sorry that it's taking so long to address but this is not a trivial task as it needs to go through deprecation phases in dry-logic and dry-schema as it uses this predicate.

In #98 I am addressing the rename and the deprecation here. Then I will follow up with deprecation/rename in dry-schema.

The final fix, which is of course removing this predicate completely, will happen in 2.0.0s of both dry-logic and dry-schema.

In an intermediate release, I'll point to this issue and explain that it might be a good idea to redefine this method in your code "just in case" and use is_eql? from now on.

I will close this issue after the final removal is done in 2.0.0. We'll be releasing it before the end of the year, if things go well, if not - early 2023.

Stay tuned 🙂

Just a short update that I ended up tweaking eql? to work like Object#eql? when just one arg is passed so it should work now in dry-logic 1.5.0.