From: eregontp@... Date: 2020-06-14T10:32:50+00:00 Subject: [ruby-core:98798] [Ruby master Misc#16961] Is overriding a method in a subclass considered as a breaking change or not? Issue #16961 has been updated by Eregon (Benoit Daloze). Could MJIT add its own check if called on a Fixnum, then do the inline fast-path logic, otherwise fallback to a call to the original definition? One would still need to check that Numeric#zero? is not redefined, but in all cases it's needed to check if redefined (whether it's Numeric#zero? or Integer#zero?). That would work transparently without adding a new method. Somewhat similar logic in TruffleRuby for `+`, `nil?`, etc, handling a subset of inputs, and rewriting as a call if inputs don't match that: https://github.com/oracle/truffleruby/tree/17701a09fca2fa1641353582d8c7be8216345b8a/src/main/java/org/truffleruby/core/inlined I think we should avoid many new methods on e.g. Integer/Array duplicating Numeric/Enumerable, but rather have generic tricks to be able to specialize on common cases. ---------------------------------------- Misc #16961: Is overriding a method in a subclass considered as a breaking change or not? https://bugs.ruby-lang.org/issues/16961#change-86160 * Author: k0kubun (Takashi Kokubun) * Status: Open * Priority: Normal ---------------------------------------- ## Background * In [Bug #15589], I'm going to make `Integer#zero?` faster (comparable to `== 0`) on JIT by making sure the method is inlinable by MJIT. * Currently `Integer#zero?` is not defined and it's implemented as `Numeric#zero?`. * However, `Numeric#zero?`'s method definition handles not only `Integer` but also `Rational` and `Complex`. Because `rb_equal` which calls `rb_funcall` is used for `Rational` and `Complex`, we can't predict what'd happen there and it prevents `Numeric#zero?` from being inlined by MJIT. Moreover, reducing inlined code size is always good for JIT-ed code. So specializing `Numeric#zero?` to `Integer#zero?` will be beneficial for MJIT's inlining regardless of `rb_funcall`'s presence. * So I'd like to define `Integer#zero?` for optimizing JIT-ed code of `zero?` call against `Integer`. ## Discussion Theoretically, overriding a method in a subclass in Ruby core might change an existing application's behavior (If a user overwrote `Numeric#zero?` and then Ruby core overwrote `Integer#zero?`, the user's definition would get suddenly ignored for Integer). How should we decide whether the change is acceptable or not? Some possible ideas: * Search all gems using gem-codesearch and check if there's any code to be broken. * In `Integer#zero?`'s case I found [this code](https://github.com/ninjudd/rupture/blob/v0.3.0/lib/rupture/core_ext.rb#L18-L20) but it's not gonna be broken by overriding `Integer#zero?`. Other `zero?` method definitions seemed for other classes, but I can double check every occurrence if this will be the measure. * Discuss and make a decision on case-by-case basis. * In `Integer#zero?`'s case we'll discuss whether overriding `Integer#zero?` is acceptable or not. -- https://bugs.ruby-lang.org/ Unsubscribe: