Sleight of Hand for the Ruby Man

June 12th, 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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

module Kernel

  # which { some_object.some_method() } => <file>:<line>:
  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
    
    # def self.crazy_custom_finder
    #  return find(:all......)
    # end
    # return unless event == 'call' or (event == 'return' and classname.included_modules.include?(ActiveRecord::Associations))
    # which_file = "Line \##{line} of #{file}"
    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

1
2
3

>> 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.

1 Response to “Sleight of Hand for the Ruby Man”

  1. Mark Wilden Says:
    It's "sleight." -- Amateur Magician

Sorry, comments are closed for this article.

-U:**- index.html.erb   (Ruby RoR RHTML)
M-x visit-site http://aaronbedra.com