detective 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -14,7 +14,8 @@ View the source of a class method ...
14
14
  require 'detective'
15
15
 
16
16
  Detective.view_source('ActiveRecord::Base.find_by_sql')
17
-
17
+
18
+ Result
18
19
  def find_by_sql(sql)
19
20
  connection.select_all(sanitize_sql(sql), "#{name} Load").collect! { |record| instantiate(record) }
20
21
  end
@@ -23,6 +24,7 @@ View the source of an instance method ...
23
24
 
24
25
  Detective.view_source('ActiveRecord::Base#update_attributes')
25
26
 
27
+ Result
26
28
  def update_attributes(attributes)
27
29
  self.attributes = attributes
28
30
  save
@@ -39,6 +41,7 @@ View the source of an overrided method ...
39
41
 
40
42
  Detective.view_source('ActiveRecord::Base#update_attributes')
41
43
 
44
+ Result
42
45
  def update_attributes(attributes)
43
46
  puts "updating attributes ..."
44
47
  self.attributes = attributes
@@ -48,13 +51,32 @@ View the source of an overrided method ...
48
51
  Find the location of some source ...
49
52
  Detective.get_location('ActiveRecord::Base#attributes')
50
53
 
54
+ Result
51
55
  location
52
56
  /home/aseldawy/.gem/ruby/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb
53
57
  2752
54
58
 
59
+ (new) You can also find source code for modules ...
60
+ Detective.view_source('AuthenticatedSystem#current_user')
61
+
62
+ Result
63
+ def current_user
64
+ @current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie) unless @current_user == false
65
+ end
66
+
67
+ (new) You have an alternative output ...
68
+ Detective.view_source('AuthenticatedSystem#current_user', :rdoc)
69
+
70
+ Result
71
+ /home/aseldawy/aptana_studio/archiving_system/lib/authenticated_system.rb, line 11
72
+ 11: def current_user
73
+ 12: @current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie) unless @current_user == false
74
+ 13: end
75
+
55
76
  No luck with native methods ...
56
77
  Detective.view_source('String#length')
57
-
78
+
79
+ Result
58
80
  native method
59
81
 
60
82
  == How it works (advanced)
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ begin
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "detective"
8
8
  gem.summary = "Find source code of ruby methods"
9
- gem.description = "A gem that allows you to view the source code of a method"
9
+ gem.description = "A ruby gem built by BadrIT (http://www.badrit.com/) that allows you to view the source code of a method"
10
10
  gem.email = "ahmed.eldawy@badrit.com"
11
11
  gem.homepage = "http://github.com/aseldawy/detective"
12
12
  gem.authors = ["Ahmed ElDawy"]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
data/detective.gemspec CHANGED
@@ -5,12 +5,12 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{detective}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ahmed ElDawy"]
12
- s.date = %q{2009-11-20}
13
- s.description = %q{A gem that allows you to view the source code of a method}
12
+ s.date = %q{2009-11-21}
13
+ s.description = %q{A ruby gem built by BadrIT (http://www.badrit.com/) that allows you to view the source code of a method}
14
14
  s.email = %q{ahmed.eldawy@badrit.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
data/lib/detective.rb CHANGED
@@ -2,9 +2,14 @@ require 'ruby_parser'
2
2
 
3
3
  module Detective
4
4
 
5
- ForkSupported = respond_to? :fork
5
+ begin
6
+ fork {exit!}
7
+ ForkSupported = true
8
+ rescue Exception
9
+ ForkSupported = false
10
+ end
6
11
 
7
- def self.view_source(method)
12
+ def self.view_source(method, format=:plain)
8
13
  location = get_location(method).strip.split /[\r\n]+/
9
14
  case location.first
10
15
  when 'native method' then return 'native method'
@@ -15,19 +20,29 @@ module Detective
15
20
  line_no = line_no.to_i
16
21
  f = File.open filename
17
22
  source = ""
18
- file_line_no = 0
23
+ output = case format
24
+ when :plain then ""
25
+ when :rdoc then "#{filename}, line #{line_no}" << "\r\n"
26
+ else ""
27
+ end
28
+ current_line_no = 0
19
29
  rp = RubyParser.new
20
- f.each_line do |file_line|
21
- file_line_no += 1
22
- if file_line_no >= line_no
23
- source << file_line
30
+ f.each_line do |current_line|
31
+ current_line_no += 1
32
+ if current_line_no >= line_no
33
+ output << case format
34
+ when :plain then current_line
35
+ when :rdoc then "#{current_line_no}:#{current_line}"
36
+ else current_line
37
+ end
38
+ source << current_line
24
39
  # Try to parse it to know whether the method is complete or not
25
40
  rp.parse(source) && break rescue nil
26
41
  end
27
42
  end
28
43
  f.close
29
- return source
30
- rescue
44
+ return output
45
+ rescue Exception => e
31
46
  return "Cannot find source code"
32
47
  end
33
48
  end
@@ -62,31 +77,31 @@ private
62
77
  end
63
78
  result = ""
64
79
  t = Thread.new do
65
- # child process
66
- detective_state = 0
67
- # Get an instance of class Method that can be invoked using Method#call
68
- the_method, args = get_method(the_klass, method_name, class_method)
69
- set_trace_func(proc do |event, file, line, id, binding, classname|
70
- if id == :call
71
- detective_state = 1
72
- return
73
- end
74
- return if detective_state == 0
75
- if event == 'call'
76
- result << "location" << "\r\n"
77
- result << file << "\r\n"
78
- result << line.to_s << "\r\n"
79
- # Cancel debugging
80
- set_trace_func nil
81
- Thread.kill(Thread.current)
82
- elsif event == 'c-call'
83
- result << 'native method'
84
- set_trace_func nil
85
- Thread.kill(Thread.current)
86
- end
87
- end)
88
-
89
80
  begin
81
+ # child process
82
+ detective_state = 0
83
+ # Get an instance of class Method that can be invoked using Method#call
84
+ the_method, args = get_method(the_klass, method_name, class_method)
85
+ set_trace_func(proc do |event, file, line, id, binding, classname|
86
+ if id == :call
87
+ detective_state = 1
88
+ return
89
+ end
90
+ return if detective_state == 0
91
+ if event == 'call'
92
+ result << "location" << "\r\n"
93
+ result << file << "\r\n"
94
+ result << line.to_s << "\r\n"
95
+ # Cancel debugging
96
+ set_trace_func nil
97
+ Thread.kill(Thread.current)
98
+ elsif event == 'c-call'
99
+ result << 'native method'
100
+ set_trace_func nil
101
+ Thread.kill(Thread.current)
102
+ end
103
+ end)
104
+
90
105
  the_method.call *args
91
106
  # If the next line executed, this indicates an error because the method should be cancelled before called
92
107
  result << "method called!" << "\r\n"
@@ -102,30 +117,30 @@ private
102
117
  def self.get_location_fork(the_klass, method_name, class_method)
103
118
  f = open("|-", "w+")
104
119
  if f == nil
105
- # child process
106
- detective_state = 0
107
- # Get an instance of class Method that can be invoked using Method#call
108
- the_method, args = get_method(the_klass, method_name, class_method)
109
- set_trace_func(proc do |event, file, line, id, binding, classname|
110
- if id == :call
111
- detective_state = 1
112
- return
113
- end
114
- return if detective_state == 0
115
- if event == 'call'
116
- puts "location"
117
- puts file
118
- puts line
119
- set_trace_func nil
120
- exit!
121
- elsif event == 'c-call'
122
- puts 'native method'
123
- set_trace_func nil
124
- exit!
125
- end
126
- end)
127
-
128
120
  begin
121
+ # child process
122
+ detective_state = 0
123
+ # Get an instance of class Method that can be invoked using Method#call
124
+ the_method, args = get_method(the_klass, method_name, class_method)
125
+ set_trace_func(proc do |event, file, line, id, binding, classname|
126
+ if id == :call
127
+ detective_state = 1
128
+ return
129
+ end
130
+ return if detective_state == 0
131
+ if event == 'call'
132
+ puts "location"
133
+ puts file
134
+ puts line
135
+ set_trace_func nil
136
+ exit!
137
+ elsif event == 'c-call'
138
+ puts 'native method'
139
+ set_trace_func nil
140
+ exit!
141
+ end
142
+ end)
143
+
129
144
  the_method.call *args
130
145
  # If the next line executed, this indicates an error because the method should be cancelled before called
131
146
  puts "method called!"
@@ -146,8 +161,11 @@ private
146
161
  def self.get_method(the_klass, method_name, class_method)
147
162
  if class_method
148
163
  the_method = the_klass.method(method_name)
149
- else
150
- # Create a new empty initialize method to bypass initialization
164
+ elsif the_klass.is_a? Class
165
+ # Create an instance of the given class
166
+ # Create a new empty initialize method to bypass initialization ...
167
+ # because some classes require special attributes when created.
168
+ # Some other like ActiveRecord::Base does not allow to be instantiated at all
151
169
  the_klass.class_eval do
152
170
  alias old_initialize initialize
153
171
  def initialize
@@ -161,6 +179,11 @@ private
161
179
  # undef initialize
162
180
  alias initialize old_initialize
163
181
  end
182
+ elsif the_klass.is_a? Module
183
+ # Crate any object and let it extends the given module
184
+ object = Object.new
185
+ object.extend the_klass
186
+ the_method = object.method(method_name)
164
187
  end
165
188
  # check how many attributes are required
166
189
  the_method_arity = the_method.arity
@@ -1,15 +1,15 @@
1
1
  require 'helper'
2
2
 
3
- class BadrIT; end
3
+ class BadrIT
4
+ def self.hello
5
+ puts "hello BadrIT"
6
+ end
7
+ end
8
+ module IPhone; end
9
+
4
10
 
5
11
  class TestDetective < Test::Unit::TestCase
6
12
  def test_simple_method
7
- BadrIT.class_eval do
8
- def self.hello
9
- puts "hello BadrIT"
10
- end
11
- end
12
-
13
13
  source = Detective.view_source('BadrIT.hello')
14
14
  assert_equal 'def self.hello puts "hello BadrIT" end', source.gsub(/\s+/, ' ').strip
15
15
  end
@@ -137,5 +137,20 @@ class TestDetective < Test::Unit::TestCase
137
137
  Detective.view_source('BadrIT')
138
138
  end
139
139
  end
140
+
141
+ def test_moudle_source
142
+ IPhone.module_eval do
143
+ def app_store
144
+ puts "app_store!"
145
+ end
146
+ end
147
+
148
+ source = Detective.view_source('IPhone#app_store')
149
+ assert_equal 'def app_store puts "app_store!" end', source.gsub(/\s+/, ' ').strip
150
+ end
140
151
 
152
+ def test_rdoc_format
153
+ source = Detective.view_source('BadrIT.hello', :rdoc)
154
+ assert_equal "#{__FILE__}, line 4 4: def self.hello 5: puts \"hello BadrIT\" 6: end", source.gsub(/\s+/, ' ').strip
155
+ end
141
156
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: detective
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ahmed ElDawy
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-20 00:00:00 +02:00
12
+ date: 2009-11-21 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,7 +22,7 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: "0"
24
24
  version:
25
- description: A gem that allows you to view the source code of a method
25
+ description: A ruby gem built by BadrIT (http://www.badrit.com/) that allows you to view the source code of a method
26
26
  email: ahmed.eldawy@badrit.com
27
27
  executables: []
28
28