| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
`a == b` is answered by `OP_EQ`, which takes two values for equal where they are the same object and dispatches `==` only after. `mrb_equal()` is that same test made from C, and it is what `Array#index` and `#delete` search a pair with. `Array#==` dispatched `==` per element instead, going around it, so an object whose `==` answers false to everything was not equal to itself inside an array while it was equal to itself outside one. ```ruby class Never def ==(other); false; end end n = Never.new [n].index(n) # 0 [n] == [n] # before false, CRuby true ``` CRuby compares the elements here the same way `#index` does, and so does this now.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 18fbca10-1022-4df9-ab4c-e24a575db076 📥 CommitsReviewing files that changed from the base of the PR and between 44ab336 and 8b0c2ef. 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 Walkthrough WalkthroughArray#== now compares elements with mrb_equal(). Tests cover identical objects whose explicit == method returns false, including Array#index. ChangesArray equality behavior
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to 8b0c2 This localized change aligns Array#== with the existing identity-first equality behavior used by other array searches and adds coverage; no actionable merge-blocking risk remains after normal checks and review. Suggested reviewers: matz, leviongit 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. ❤️ ShareComment @coderabbitai help to get the list of available commands. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Summary
a == b is answered by OP_EQ, which takes two values for equal where they are the same object and dispatches == only after. mrb_equal() is that same test made from C, and it is what Array#index and #delete search a pair with. Array#== dispatched == at each element instead, going around it, so an object was equal to itself outside an array and not inside one.
Changes
The one comparison that asks nothing of the object
mrb_equal() looks for the object first and asks == after. Every other search an array makes reads a pair that way, and OP_EQ reads one that way before it dispatches anything; mrb_ary_eq() was the exception.
CRuby compares elements here the same way it compares them in #index, and so does this now. An element whose == answers as == should is found by == as before, one comparison earlier.
Behaviour
n is an object whose == answers false to everything; a and b are two NaNs built at run time as z / z from z = [0.0][0], so that nothing folds them into a single literal. Bold marks a row that differs from CRuby.
The last two rows are one answer. A NaN is equal to no value, its own operand included, so == can never find one and only the object is left to go by; where a boxing keeps a Float in the value, every NaN is normalized to one representation, so two NaNs made apart are one object. #index has been saying so on master all along, and #== says it now too. Making a NaN an object of its own is a change to what a Float is rather than to how an array compares, and it is not in this PR.
Speed
Best of 11 interleaved runs against master, with a master-vs-master control to read the noise by, and the instruction counts callgrind reads beside them:
mrb_equal() in place of a method dispatch at each of the 200 elements is what #index already paid for the same walk.
Size
bin/mruby .text for every build in build_config/ci/gcc-clang.rb:
The whole of it is src/array.o, which shrinks by 80 bytes: a call to mrb_funcall_argv1() with a symbol and an argument array goes away, and mrb_equal() takes its place.
Testing
rake test passes for the default build, for build_config/host-nofloat.rb, for every build in build_config/ci/gcc-clang.rb including the C++ ABI one, and for a MRB_NO_BOXING build of the full-core gembox, with no compiler warnings beyond the one -Wmaybe-uninitialized about eq in hash.c that master already emits in a MRB_NO_BOXING build. The last of those is there because the rows about a NaN in the table above are ones a boxing decides.
Environment
Machine, toolchain and the compile lines these numbers were taken withThe wall clock and instruction counts were taken with the default build:
gcc -std=gnu99 -g -O3 -Wall -Wundef -Werror-implicit-function-declaration -Wwrite-strings -DHAVE_MRUBY_REGEXP_GEM -DMRB_USE_SET -DHAVE_MRUBY_IO_GEM -DMRB_USE_RATIONAL -DMRB_USE_COMPLEX -DMRB_USE_BIGINT -DMRB_USE_DEBUG_HOOKThe ## Size table was taken with build_config/ci/gcc-clang.rb:
cxx_abi compiles mruby as C++ with gcc -x c++ -std=gnu++03; g++ only links. full-debug is the one build at -O0, enable_debug putting -g3 -O0 after the toolchain default of -g -O3.
Summary by CodeRabbit
Bug Fixes
Tests