While browsing through the source code of a gem recently, I came across something I hadn't seen in a while: refinements.
Refinements were introduced in Ruby 2.4 as a better alternative to monkey-patching. It allows to override a core class method in a limited scope. On the other hand, monkey patching changes the method across the whole program.
Here's the example I saw:
# frozen_string_literal: true
 
module Isolator
  module ThreadFetch 
    refine Thread do
      def fetch(key, fallback = :__undef__)
        raise KeyError, "key not found: #{key}" if !key?(key) && fallback == :__undef__
 
        self[key] || fallback
      end
    end
  end
endThis overrides Thread's fetch method.
Later in the same gem, it's used like this
module Isolator
  using Isolator::ThreadFetch
 
  class ThreadStateProxy
    # Only within this scope, Thread#fetch behaves as defined above
    ...
  end
endWhat's nice here is that Thread#fetch isn't changed globally. The override only applies inside the Isolator::ThreadStateProxy module. Other parts of the app that use Thread won't be affected.