Find code that busts the Ruby 2.1+ cache.
Ruby DTrace
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
dtrace/probes
lib
test
.gitignore
.ruby-version
.travis.yml
CONTRIBUTING.md
Gemfile
LICENSE.txt
README.md
Rakefile
busted.gemspec

README.md

Busted Build Status Code Climate

Find code that busts the Ruby 2.1+ cache.

Busted reports when code invalidates Ruby's internal cache.

Basic Usage

Any Cache

Busted.cache? do
  class Beer
  end
end
#=> true

Busted.run do
  class Pizza
  end
end
#=> {:invalidations=>{:method=>0, :constant=>1}}

Busted.start
class Pie
end
Busted.finish
#=> {:invalidations=>{:method=>0, :constant=>1}}

Method Cache

Busted.method_cache? do
  def beer
  end
end
#=> true

Busted.method_cache_invalidations do
  def pizza
  end
end
#=> 1

Busted.run do
  def pie
  end
end
#=> {:invalidations=>{:method=>1, :constant=>0}}

Busted.start
def smoothie
end
Busted.finish
#=> {:invalidations=>{:method=>1, :constant=>0}}

Constant Cache

Busted.constant_cache? do
  STOUT = "stout"
end
#=> true

Busted.constant_cache_invalidations do
  CHEESE = "cheese"
end
#=> 1

Busted.run do
  PIE = "pumpkin"
end
#=> {:invalidations=>{:method=>0, :constant=>1}}

Busted.start
SMOOTHIE = "blueberry"
Busted.finish
#=> {:invalidations=>{:method=>0, :constant=>1}}

No Cache Busted

Busted.cache? do
  beer = "beer"
end
#=> false

Busted.run do
  pizza = "pizza"
end
#=> {:invalidations=>{:method=>0, :constant=>0}}

Busted.start
pie = "pie"
Busted.finish
#=> {:invalidations=>{:method=>0, :constant=>0}}

Advanced Usage

Busted can report method cache invalidation locations via dtrace. The running process must have root privileges, and dtrace must be installed.

trace.rb

require "busted"
require "pp"

report = Busted.run(trace: true) do
  def cookie
  end
end
pp report
$ whoami
simeon

$ id simeon
uid=501(simeon) gid=20(staff) groups=20(staff),80(admin)

# simeon is an admin; sudo does not require a password
$ sudo grep admin /etc/sudoers
%admin	ALL=(ALL) NOPASSWD: ALL

$ sudo dtrace -V
dtrace: Sun D 1.6.2

# No need to sudo
# Busted runs dtrace in a child process with root privileges
$ ruby trace.rb
{:invalidations=>{:method=>1, :constant=>0},
 :traces=>
  {:method=>[{:class=>"global", :sourcefile=>"trace.rb", :lineno=>"5"}]}}

start_finish_trace.rb

require "busted"
require "pp"

Busted.start trace: true
def ice_cream
end
pp Busted.finish
$ ruby start_finish_trace.rb
{:invalidations=>{:method=>1, :constant=>0},
 :traces=>
  {:method=>
    [{:class=>"global", :sourcefile=>"start_finish_trace.rb", :lineno=>"5"}]}}

Busted includes an example dtrace probe for use on the command line or an application. See the probe for usage.

Installation

Requires MRI Ruby 2.1+

Add this line to your application's Gemfile:

gem "busted"

And then execute:

$ bundle

Or install it yourself as:

$ gem install busted

Contributing

Check out this guide if you'd like to contribute.

License

This project is licensed under the MIT License.

Standing On The Shoulders Of Giants

A big thank you to Charlie Somerville and Aman Gupta for helping flesh out RubyVM.stat and committing it to Ruby core!