Skip to content

Document Option equality semantics; resolve the None == nil TODO - #35

Merged
nz merged 1 commit into
mainfrom
docs/option-equality-semantics
Aug 7, 2026
Merged

nz merged 1 commit into
mainfrom
docs/option-equality-semantics

Conversation

@nz

@nz nz commented Aug 7, 2026

Copy link
Copy Markdown
Member

Closes #20 as won't-fix-the-behavior, with the docs the issue asked for as the fallback.

The issue wants Some(5) == 5 to raise TypeMismatchError. Declining the raise: == is called pervasively with heterogeneous operands in Ruby — [Some(1), "x"].include?(Some(1)) calls Some(1) == "x", assert_equal 1, opt diffs across types, ActiveRecord dirty tracking compares old/new attribute values — and every other Ruby object answers cross-type == with false. A raise converts silent-wrong into loud-wrong at innocent call sites, which is the worse trade. The discoverability gap is instead covered by #33's teaching UnwrappedAccessError and #29's readable inspect, which make a mistyped comparison visible the moment anything touches the value.

What this PR does:

  • Resolves the TODO: does None == nil? — the answer is no, None() == nil stays false. None is a value representing absence, not an absence Ruby can see. The Rails shim's None#nil? == true is documented as an ActiveRecord compromise that equality deliberately does not follow (Document the ActiveRecord pragmatic compromises in ActiveRecordOptional #25 covers the compromise set).
  • Rewrites the == doc comment with the rationale and the idioms (opt == Some(5), opt.some_and? { |v| v == 5 }), removing the stale strict: sketch.
  • Adds the equality paragraph to the README's Option section.

No behavior change; the existing == doctests already pin all six cases.

Cross-type == stays quietly false rather than raising: Rust rejects
Some(5) == 5 at compile time, but Ruby compares heterogeneous
operands pervasively (Array#include?, assertion diffs, dirty
tracking), so raising from == would break innocent call sites.
None() == nil stays false; the Rails shim's None#nil? compromise
does not extend to equality. Point to opt == Some(x) and some_and?
as the idioms.

Closes #20.
@nz
nz merged commit 3c372e1 into main Aug 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Option: Some(5) == 5 returns false silently where Rust would be a type error

2 participants