Skip to content

wegowise/watchdog

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
lib
 
 
 
 
 
 
 
 
 
 

Description

Watchdog ensures your extensions and monkey patches don't redefine existing methods as well as get redefined by others.

Install

$ gem install watchdog

Usage

Let's say we want to add an instance method to String with extension module ToDate:

module ToDate
  def to_date
    Date.parse(self)
  end
end

String.send :include, ToDate

What happens if String#to_date already exists? What happens if another gem redefines that method later? Breakage.

Watchdog watches over these concerns with a simple extend:

module ToDate
  extend Watchdog

  def to_date
    Date.parse(self)
  end
end

String.send :include, ToDate

Now if String#to_date already exists, watchdog raises a runtime error. Same goes if someone tries to redefine the method later:

>> class String; def to_date; p 'HAHAHA'; end; end
Watchdog::ExtensionMethodExistsError: Date not allowed to redefine extension method from ToDate#to_date
    ./lib/watchdog.rb:13:in `guard'
    ./lib/watchdog/german_shepard.rb:23:in `method_added'
    (ripl):3

Watchdog also guards over extension modules that define class methods:

module DaysTillXmas
  extend Watchdog

  def days_till_xmas
    Date.new(Date.today.year, 12, 25) - Date.today
  end
end

Date.extend DaysTillXmas
# Date.days_till_xmas ->  253  NOOOOO...

Caveats

Watchdog's protectiveness can be problematic with mocks in a test suite as they love to redefine methods. Watchdog provides Watchdog.sleep, a Proc to conditionally turn off guarding extension methods. By default, Watchdog sets this so that Rspec mocks are allowed to slip by:

Watchdog.sleep = lambda { defined? RSpec && !caller.grep(/rspec-mocks/).empty? }

Credits

Thanks to Wegowise for open-source time to make this possible!

License

See LICENSE.txt

About

Ensures your extensions and monkey patches don't redefine existing methods as well as get redefined by others.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages