Class: Inspector

Inherits:
Object
  • Object
show all
Defined in:
lib/inspector.rb

Class Method Summary collapse

Class Method Details

._collect_events_for_method_call(&block) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/inspector.rb', line 7

def self._collect_events_for_method_call(&block)

  events = []
  
  set_trace_func lambda { |event, file, line, id, binding, classname|
    events << { :event => event, :file => file, :line => line, :id => id, :binding => binding, :classname => classname }
  }
  
  begin
    yield
  ensure
    set_trace_func(nil)
  end

  events
end

._trace_the_method_call(&block) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/inspector.rb', line 24

def self._trace_the_method_call(&block)
  events = _collect_events_for_method_call &block
  
  # events.reject! { |event| !%w{call c-call return}.include?(event[:event]) }
  valid_event_types = ['call', 'c-call', 'return']
  
  events.each do |event|
    next unless valid_event_types.include?(event[:event])
    
    case event[:classname].to_s
      when 'ActiveRecord::Base'
        return events[-3]
      else
        return event if event[:event].include?('call')
    end
  end

end

.detector(&block) ⇒ Object



81
82
83
84
85
86
# File 'lib/inspector.rb', line 81

def self.detector(&block)
  where = where_is_this_defined(&block)
  how = how_is_this_defined(&block)
  
  "Sir, here are the details of your inquiry:\n\nThe method in question was found to be defined in:\n#{where}\n\nAlso, it was found to look like the following on the inside:\n#{how}\n\n"
end

.how_is_this_defined(&block) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/inspector.rb', line 56

def self.how_is_this_defined(&block)
  begin
    event = _trace_the_method_call(&block)

    if event
      RubyToRuby.translate(event[:classname], event[:id])
    else
      "Unable to determine where the method was defined in order to get to it's source"
    end
  rescue RuntimeError => rte
    # Assuming class level method
    return RubyToRuby.translate(event[:classname], "self.#{event[:id]}")
  rescue NoMethodError => nme
    if nme.message =~ /^undefined method \`(.*)\' for nil\:NilClass/
      return "Unable to get the source for #{event[:classname]}.#{event[:id]} because it is a function defined in C"
    end 
    raise
  rescue Exception => ex
    if event[:classname].to_s == 'ActiveRecord::Base'
      return "Sorry, Ruby2Ruby can't peek under the hood in ActiveRecord::Base (modules + classes == fail in ruby2ruby)"
    end
    raise
  end
end

.where_is_this_defined(&block) ⇒ Object

Original version from holgerkohnen.blogspot.com/ which { some_object.some_method() } => <file>:<line>:



45
46
47
48
49
50
51
52
53
54
# File 'lib/inspector.rb', line 45

def self.where_is_this_defined(&block)
  event = _trace_the_method_call(&block)

  if event
    # TODO: If the file is (irb) or event[:event] is c-call note it differently in the output
    "#{event[:classname]} received message '#{event[:id]}', Line \##{event[:line]} of #{(event[:event] == 'c-call') ? 'the Ruby Standard Library' : event[:file]}"
  else
    "Unable to determine where the method was defined"
  end
end