detective 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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