Open source

Open Source

Contributions to the Ruby ecosystem: pull requests to projects I use and libraries I maintain.

Merged into Ruby
ruby/ruby

Contributions to Ruby

Patches merged into the language and the standard library that ships with it.

Ruby
  1. Fix link_local_multicast? mask for IPv4-mapped addresses

    ruby/ipaddr

    September 2026 · IPAddr · +8 −1

    Merged

    IPAddr.new('224.0.1.1').link_local_multicast? returned false while ::ffff:224.0.1.1 returned true — the same address, answered differently depending on the form it arrived in. The IPv4 branch masked the documented /24, the IPv4-mapped branch a /16, and a dual-stack AF_INET6 socket hands out the mapped form. Every other predicate in the family already used the same mask on both branches.

    RubyIPAddrNetworking
  2. [DOC] Pathname#rmtree returns self, not 0

    September 2026 · Pathname · +4 −2

    Merged

    The docs promised a 0 return value in both the call-seq and the prose, but the method has returned self since mkpath and rmtree were made chainable — and test_rmtree asserts exactly that. The call-seq also dropped the keyword arguments, which are now documented alongside a pointer to FileUtils.rm_rf, where they are forwarded.

    RubyPathnameDocumentation
Merged into Rails
rails/rails

Contributions to Ruby on Rails

Patches merged into Rails itself, reviewed and shipped by the core team.

Ruby on Rails
  1. Apply the table name prefix to the index name 4.2 migrations compute

    October 2026 · Active Record · +54 −2

    Merged

    In a migration tagged [4.2], index_exists? and remove_index worked out the index name from the table name as written, before Migration#method_missing added the prefix. With table_name_prefix set, the index on disk is index_p_testings_on_foo while both looked for index_testings_on_foo, so remove_index raised ArgumentError and index_exists? answered false for an index that exists. Both now compute the name from the prefixed table, the same fix V5_1#change_column already had.

    Active RecordMigrationsCompatibility
  2. Don't assume a tagging logger keeps tags in its formatter

    September 2026 · Action Cable · +34 −2

    Merged

    TaggedLoggerProxy#tag checked logger.respond_to?(:tagged) and then read logger.formatter.current_tags. Once BroadcastLogger gained its own tagged, that check stopped implying the formatter keeps tags, and a BroadcastLogger over plain loggers has no formatter at all, so NoMethodError was raised. Every log line goes through tag, so it broke Action Cable for anyone sending logs to more than one place. The tags are now read only when the formatter actually keeps them, matching the fix Active Job already had.

    Action CableLoggingBroadcast logger
  3. Treat false as disabled for idle_timeout, reaping_frequency and max_age

    September 2026 · Active Record · +51 −7

    Merged

    YAML reads off and no as false, so idle_timeout: off in database.yml is an easy spelling to reach — and it crashed the boot with NoMethodError: undefined method 'to_f' for false, since HashConfig called to_f/to_i on the value. false now disables the setting, like the documented 0, and true takes the default. The same values already worked through DATABASE_URL, where they arrive as strings.

    Active RecordConnection poolConfiguration
  4. Fix non-ASCII strict locals defaults in ASCII-only templates

    September 2026 · Action View · +13 −2

    Merged

    A non-ASCII default in the locals: magic comment rendered as mojibake — (label: "café") reached the page as caf��, with no exception raised. Erubi starts its buffer as ASCII-8BIT and only promotes it to UTF-8 once non-ASCII text is appended, so an ASCII-only body left compiled_source retagging the whole method definition, UTF-8 declaration included. The existing test happened to carry an accent in the template body, which promoted the output and hid the case.

    Action ViewEncodingERB
  5. Preserve read_multi key order when local cache is active

    September 2026 · Active Support · +28 −1

    Merged

    Inside with_local_cache, read_multi returned local cache hits first instead of following the requested order, so read_multi("a", "b", "c") could come back as b, a, c. The same bug had already been fixed for fetch_multi, but read_multi_entries, which builds its result the same way, was left behind. The result is now sliced by the requested names, and keys that were not found stay absent rather than being filled with nil.

    Active SupportCaching
  6. Check PATCH and QUERY in routing assertions with method: :all

    September 2026 · Action Pack · +42 −1

    Merged

    assert_routing with method: :all claims to check every verb but only iterated over GET, POST, PUT and DELETE, so a route that rejects PATCH or QUERY still passed. The list predated PATCH becoming the default verb for updates in Rails 4. Both verbs are now checked, and the option finally has documentation.

    Action PackRoutingTesting
  7. Fix encrypted fixtures for JSON columns

    August 2026 · Active Record · +34 −8

    Merged

    With encrypt_fixtures enabled, a fixture for an encrypts attribute on a json or jsonb column raised a decryption error on read: the payload was serialized twice, so the database stored "{\"p\":...}" instead of the JSON object. Fixtures now hand the payload back in the column's cast form, so it is written exactly once. Fixes a bug open since 2023.

    Active RecordEncryptionFixtures
  8. Document that RedisCacheStore counters and clear return nil on failure

    October 2026 · Active Support · Documentation · +6 −6

    Merged

    increment, decrement and clear were documented as raising errors, but all three run inside failsafe, which hands the exception to the error handler and returns nil, as the store's own failure tests already assert. The comments now say so, in RedisCacheStore and DeprecatedRedisCacheStore; delete_matched, which really raises, keeps its note.

    Active SupportCachingDocumentation
matz/spinel

Contributions to Spinel

Fixes and features merged into Spinel, Matz's ahead-of-time Ruby compiler.

  1. A bare raise in an ensure re-raises the exception in flight

    October 2026 · Exceptions · +24 −1

    Merged

    A bare raise only re-raised inside a rescue body, where the class and message are known at compile time. An ensure reached while unwinding carries an exception too, and there Spinel raised a new, empty RuntimeError: a raise ArgumentError, "b" followed by a bare raise in the ensure came out as ["RuntimeError", ""] where CRuby gives ["ArgumentError", "b"]. It now re-raises what sp_cur_handled answers, the same value $! already read correctly in that position, and keeps the empty RuntimeError when nothing is in flight.

    SpinelCompilerExceptions
  2. A subclass reader wins over an inherited def on a poly receiver

    October 2026 · Codegen · +21 −0

    Merged

    When a call site could receive objects of several classes, Spinel took any method found in the receiver's ancestor chain before looking for an attribute reader, so a superclass def shadowed a subclass's attr_reader. [Window.new, Other.new].each { |o| p o.seek_to } printed 0.0, 0.0 where CRuby prints 38.0, 0.0. Both call planners now ask comp_resolve_member, which already ranks a method against an attribute by which class defines it nearer.

    SpinelCompilerMethod dispatch
  3. Add Array#intersection for core typed arrays (int/sym/str/float)

    April 2026 · Arrays · +123 −0

    Merged

    Implements Array#intersection for Spinel's typed arrays, reusing the existing include? runtime functions and keeping NaN semantics consistent with Ruby for float_array. Includes tests for duplicates, empty arrays and no-match cases.

    SpinelCompilerArrays

rails_tracepoint_stack

v0.5.0 · 4.8k downloads · 35 stars

Runtime call tree for Rails: which of your methods ran, with what params, and what they returned, with gems and the framework filtered out. Built on top of Ruby's TracePoint.

RubyRailsTracePointObservability