Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-5660

Epic: Mongoid Kernel Monkey Patch Removal

    • Type: Icon: Epic Epic
    • Resolution: Fixed
    • Priority: Icon: Unknown Unknown
    • 9.0.0
    • Affects Version/s: None
    • Component/s: None
    • None
    • Done
    • Remove Monkey Patches
    • 0
    • 0
    • 0
    • 100

      A "Monkey Patch" is a piece of code which modifies the behavior of a pre-existing class (refer to https://en.wikipedia.org/wiki/Monkey_patch). Mongoid contains 125 unique cases of monkey patches, which add to or alter the behavior of Ruby's core "kernel" classes such as Object, String, Symbol, Array, Integer, and so on.

      Unlike Rails' ActiveSupport library which contains well-planned, user-oriented "convenience method" monkey patches, the vast majority of Mongoid's monkey patches are hacks which been added in a haphazard, one-off manner to achieve objectives within Mongoid's own codebase that could have been accomplished otherwise.

      Here's an article from a Rails core team member explaining the dangers of monkey patches. To summarize, Monkey patches can:

      • make upgrading and refactoring difficult
      • create surprising application behavior
      • cause conflicts between Mongoid and other libraries
      • cause security issues
      • expose internal-only functionality and cause tight-coupling
      • create "magical" syntax which alters how Ruby itself typically works (see Mongoid's :symbol.in syntax)

      Mongoid users and developers alike will benefit greatly from cleaning up this mess.

      I would like to propose a worksteam to remove Mongoid's monkey patches. I believe it can be done in 4 phases:

      • Phase 1 - Quick wins. Remove one-off hacks that are only used in one or a few places.
      • Phase 2 - Remove all monkey patches associated with 
        Mongoid::Criteria::Queryable::Extensions. This includes methods like Object#{}add_from_array{}
      • Phase 3 - Remove Symbol query syntax such as where(:age.in => [26, 27]) and extract it to a gem for users who rely on it.
      • Phase 4 - Remove mongoization hacks such as Object#mongoize and replace with "Mongoizer" classes.

      Here is a spreadsheet with all monkey patch methods and the plan to remove them, starting with Phase 1:

      https://docs.google.com/spreadsheets/d/1ORuAAGrL566Ibrj8wh8RD6B32YDK_xXdld9Bi3gVd3Q/edit?usp=sharing

      • I will raise sub-tickets and individual PRs for each removal.
      • The primary objective of these PRs will be to eliminate the monkey patch but otherwise preserve the pre-existing code and tests, if they exist.
      • All removals will be done in a semver-compliant manner, and I will raise deprecation PRs as necessary.

            Assignee:
            Unassigned Unassigned
            Reporter:
            shields@tablecheck.com Johnny Shields
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: