Sleight of Hand for the Ruby Man - No Fluff Just Stuff

Sleight of Hand for the Ruby Man

Posted by: Aaron Bedra on June 12, 2008

Sleight of Hand for the Ruby Man

12 Jun 2008

Chad Humphries pointed me to this tasty bit of code. Since Ruby so graciously lets you open up classes anywhere, it’s nice to know where the right place to debug is. Simply put the following code into a globally accessible place (I just used .irbrc) and you will have the method available.

module Kernel
  def where_is_this_defined(settings={}, &block)
    settings[:debug] ||= false
    settings[:educated_guess] ||= false

    events = []

    set_trace_func lambda { |event, file, line, id, binding, classname|
    events << { :event => event, :file => file, :line => line, :id => id, :binding => binding, :classname => classname }
 
    if settings[:debug]
      puts "event => #{event}"
      puts "file => #{file}"
      puts "line => #{line}"
      puts "id => #{id}"
      puts "binding => #{binding}"
      puts "classname => #{classname}"
      puts ''
    end 
    }
    yield
    set_trace_func(nil)

    events.each do |event|
      next unless event[:event] == 'call' or (event[:event] == 'return' and event[:classname].included_modules.include?(ActiveRecord::Associations))
      return "#{event[:classname]} received message '#{event[:id]}', Line \##{event[:line]} of #{event[:file]}"
    end

    if settings[:educated_guess] and events.size > 3
      event = events[-3]
      return "#{event[:classname]} received message '#{event[:id]}', Line \##{event[:line]} of #{event[:file]}"
    end

    return 'Unable to determine where method was defined.'
  end
end

Once you have that you can simply open up script/console or irb and give it a whirl

>> where_is_this_defined {Streamlined.ui_for(:foo)}
=> "Streamlined received message 'ui_for', Line #6 of /Users/abedra/src/someapp/trunk/lib/extensions/streamlined/streamlined.rb"

This tells us that the ui_for method of streamlined is actually being called from an extension that the project made rather than the streamlined plugin itself. This would save you lots of time trying to debug the wrong method! Give it a try.

Aaron Bedra

About Aaron Bedra

Aaron Bedra is a Senior Engineer at DRW, where he works at the intersection trading and technology. He has served as a Chief Security Officer, Chief Technology Officer, and Principal Engineer/Architect. He has worked professionally on programming languages, most notably Clojure and ClojureScript. Aaron is the creator of Repsheet, an open source threat intelligence toolkit. He is the co-author of Programming Clojure, 2nd and 3rd Edition and a contributor to Functional Programming: A PragPub Anthology.

Why Attend the NFJS Tour?

  • » Cutting-Edge Technologies
  • » Agile Practices
  • » Peer Exchange

Current Topics:

  • Languages on the JVM: Scala, Groovy, Clojure
  • Enterprise Java
  • Core Java, Java 8
  • Agility
  • Testing: Geb, Spock, Easyb
  • REST
  • NoSQL: MongoDB, Cassandra
  • Hadoop
  • Spring 4
  • Cloud
  • Automation Tools: Gradle, Git, Jenkins, Sonar
  • HTML5, CSS3, AngularJS, jQuery, Usability
  • Mobile Apps - iPhone and Android
  • More...
Learn More »