Due to Ruby's open classes you can redefine or add functionality to
existing classes. This is called a “monkey patch”. Unfortunately the
scope of such changes is global. All users of the monkey-patched class see
the same changes. This can cause unintended side-effects or breakage of
programs.

Refinements are designed to reduce the impact of monkey patching on other
users of the monkey-patched class. Refinements provide a way to extend a
class locally.

Here is a basic refinement:

classCdeffooputs"C#foo"endendmoduleMrefineCdodeffooputs"C#foo in M"endendend

First, a class C is defined. Next a refinement for
C is created using Module#refine. Refinements
only modify classes, not modules so the argument must be a class.

Module#refine creates an
anonymous module that contains the changes or refinements to the class
(C in the example). self in the refine block is
this anonymous module similar to Module#module_eval.

You may activate refinements at top-level, and inside classes and modules.
You may not activate refinements in method scope. Refinements are
activated until the end of the current class or module definition, or until
the end of the current file if used at the top-level.

You may activate refinements in a string passed to Kernel#eval. Refinements are
active until the end of the eval string.

Refinements are lexical in scope. Refinements are only active within a
scope after the call to using. Any code before the
using statement will not have the refinement activated.

When control is transferred outside the scope, the refinement is
deactivated. This means that if you require or load a file or call a method
that is defined outside the current scope the refinement will be
deactivated:

When defining multiple refinements in the same module inside multiple
refine blocks, all refinements from the same module are active
when a refined method (any of the to_json methods from the
example below) is called:

If refinements are active for C, in the reverse order they
were activated:

The prepended modules from the refinement for C

The refinement for C

The included modules from the refinement for C

The prepended modules of C

C

The included modules of C

If no method was found at any point this repeats with the superclass of
C.

Note that methods in a subclass have priority over refinements in a
superclass. For example, if the method / is defined in a
refinement for Numeric1 / 2
invokes the original Integer#/ because Integer is a subclass of Numeric and is searched before the
refinements for the superclass Numeric.
Since the method / is also present in child
Integer, the method lookup does not move up to the superclass.

However, if a method foo is defined on Numeric in a refinement, 1.foo
invokes that method since foo does not exist on Integer.