method_source 0.4.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -50,7 +50,6 @@ Example: display method comments
50
50
  Limitations:
51
51
  ------------
52
52
 
53
- * Proc#source not available in Ruby 1.8
54
53
  * Occasional strange behaviour in Ruby 1.8
55
54
  * Cannot return source for C methods.
56
55
  * Cannot return source for dynamically defined methods.
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ require "#{direc}/lib/method_source/version"
7
7
 
8
8
  CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o")
9
9
  CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o",
10
- "ext/**/*~", "ext/**/*#*", "ext/**/*.obj",
10
+ "ext/**/*~", "ext/**/*#*", "ext/**/*.obj", "**/*.rbc",
11
11
  "ext/**/*.def", "ext/**/*.pdb", "**/*_flymake*.*", "**/*_flymake")
12
12
 
13
13
  def apply_spec_defaults(s)
@@ -20,7 +20,10 @@ def apply_spec_defaults(s)
20
20
  s.description = s.summary
21
21
  s.require_path = 'lib'
22
22
  s.add_dependency("ruby_parser",">=2.0.5")
23
+
23
24
  s.add_development_dependency("bacon",">=1.1.0")
25
+ s.add_development_dependency("open4", "~> 1.0.1")
26
+
24
27
  s.homepage = "http://banisterfiend.wordpress.com"
25
28
  s.has_rdoc = 'yard'
26
29
  s.files = Dir["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb",
@@ -33,10 +36,10 @@ end
33
36
 
34
37
  namespace :ruby do
35
38
  spec = Gem::Specification.new do |s|
36
- apply_spec_defaults(s)
39
+ apply_spec_defaults(s)
37
40
  s.platform = Gem::Platform::RUBY
38
41
  end
39
-
42
+
40
43
  Rake::GemPackageTask.new(spec) do |pkg|
41
44
  pkg.need_zip = false
42
45
  pkg.need_tar = false
data/lib/method_source.rb CHANGED
@@ -47,7 +47,7 @@ module MethodSource
47
47
  # @return [File] The opened source file
48
48
  def self.source_helper(source_location)
49
49
  return nil if !source_location.is_a?(Array)
50
-
50
+
51
51
  file_name, line = source_location
52
52
  File.open(file_name) do |file|
53
53
  (line - 1).times { file.readline }
@@ -56,26 +56,26 @@ module MethodSource
56
56
  loop do
57
57
  val = file.readline
58
58
  code << val
59
-
59
+
60
60
  return code if valid_expression?(code)
61
61
  end
62
- end
62
+ end
63
63
  end
64
-
64
+
65
65
  # Helper method responsible for opening source file and buffering up
66
- # the comments for a specified method. Defined here to avoid polluting
66
+ # the comments for a specified method. Defined here to avoid polluting
67
67
  # `Method` class.
68
68
  # @param [Array] source_location The array returned by Method#source_location
69
69
  # @return [String] The comments up to the point of the method.
70
70
  def self.comment_helper(source_location)
71
71
  return nil if !source_location.is_a?(Array)
72
-
72
+
73
73
  file_name, line = source_location
74
74
  File.open(file_name) do |file|
75
75
  buffer = ""
76
76
  (line - 1).times do
77
77
  line = file.readline
78
- # Add any line that is a valid ruby comment,
78
+ # Add any line that is a valid ruby comment,
79
79
  # but clear as soon as we hit a non comment line.
80
80
  if (line =~ /^\s*#/) || (line =~ /^\s*$/)
81
81
  buffer << line.lstrip
@@ -83,11 +83,11 @@ module MethodSource
83
83
  buffer.replace("")
84
84
  end
85
85
  end
86
-
86
+
87
87
  buffer
88
88
  end
89
89
  end
90
-
90
+
91
91
  # This module is to be included by `Method` and `UnboundMethod` and
92
92
  # provides the `#source` functionality
93
93
  module MethodExtensions
@@ -103,7 +103,7 @@ module MethodSource
103
103
 
104
104
  klass.class_eval do
105
105
  orig_source = instance_method(:source)
106
-
106
+
107
107
  define_method(:source) do
108
108
  begin
109
109
  super
@@ -111,11 +111,11 @@ module MethodSource
111
111
  orig_source.bind(self).call
112
112
  end
113
113
  end
114
-
115
- end
114
+
116
115
  end
116
+ end
117
117
  end
118
-
118
+
119
119
  # Return the sourcecode for the method as a string
120
120
  # (This functionality is only supported in Ruby 1.9 and above)
121
121
  # @return [String] The method sourcecode as a string
@@ -129,15 +129,15 @@ module MethodSource
129
129
  def source
130
130
  if respond_to?(:source_location)
131
131
  source = MethodSource.source_helper(source_location)
132
-
132
+
133
133
  raise "Cannot locate source for this method: #{name}" if !source
134
134
  else
135
135
  raise "#{self.class}#source not supported by this Ruby version (#{RUBY_VERSION})"
136
136
  end
137
-
137
+
138
138
  source
139
139
  end
140
-
140
+
141
141
  # Return the comments associated with the method as a string.
142
142
  # (This functionality is only supported in Ruby 1.9 and above)
143
143
  # @return [String] The method's comments as a string
@@ -148,7 +148,7 @@ module MethodSource
148
148
  def comment
149
149
  if respond_to?(:source_location)
150
150
  comment = MethodSource.comment_helper(source_location)
151
-
151
+
152
152
  raise "Cannot locate source for this method: #{name}" if !comment
153
153
  else
154
154
  raise "#{self.class}#comment not supported by this Ruby version (#{RUBY_VERSION})"
@@ -170,5 +170,7 @@ class UnboundMethod
170
170
  end
171
171
 
172
172
  class Proc
173
+ include MethodSource::SourceLocation::ProcExtensions
173
174
  include MethodSource::MethodExtensions
174
175
  end
176
+
@@ -4,14 +4,14 @@ module MethodSource
4
4
 
5
5
  def trace_func(event, file, line, id, binding, classname)
6
6
  return unless event == 'call'
7
- set_trace_func nil
8
-
7
+ set_trace_func nil
8
+
9
9
  @file, @line = file, line
10
10
  raise :found
11
11
  end
12
12
 
13
13
  private :trace_func
14
-
14
+
15
15
  # Return the source location of a method for Ruby 1.8.
16
16
  # @return [Array] A two element array. First element is the
17
17
  # file, second element is the line in the file where the
@@ -19,16 +19,42 @@ module MethodSource
19
19
  def source_location
20
20
  if @file.nil?
21
21
  args =[*(1..(arity<-1 ? -arity-1 : arity ))]
22
-
22
+
23
23
  set_trace_func method(:trace_func).to_proc
24
- call *args rescue nil
25
- set_trace_func nil
24
+ call(*args) rescue nil
25
+ set_trace_func nil
26
26
  @file = File.expand_path(@file) if @file && File.exist?(File.expand_path(@file))
27
27
  end
28
28
  return [@file, @line] if File.exist?(@file.to_s)
29
29
  end
30
30
  end
31
31
 
32
+ module ProcExtensions
33
+
34
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /rbx/
35
+
36
+ # Return the source location for a Proc (Rubinius only)
37
+ # @return [Array] A two element array. First element is the
38
+ # file, second element is the line in the file where the
39
+ # proc definition is found.
40
+ def source_location
41
+ [block.file.to_s, block.line]
42
+ end
43
+
44
+ else
45
+
46
+ # Return the source location for a Proc (in implementations
47
+ # without Proc#source_location)
48
+ # @return [Array] A two element array. First element is the
49
+ # file, second element is the line in the file where the
50
+ # proc definition is found.
51
+ def source_location
52
+ self.to_s =~ /@(.*):(\d+)/
53
+ [$1, $2.to_i]
54
+ end
55
+ end
56
+ end
57
+
32
58
  module UnboundMethodExtensions
33
59
 
34
60
  # Return the source location of an instance method for Ruby 1.8.
@@ -57,7 +83,7 @@ module MethodSource
57
83
  when klass == NilClass
58
84
  return nil.method(name).source_location
59
85
  end
60
-
86
+
61
87
  begin
62
88
  klass.allocate.method(name).source_location
63
89
  rescue TypeError
@@ -1,3 +1,3 @@
1
1
  module MethodSource
2
- VERSION = "0.4.1"
2
+ VERSION = "0.6.0"
3
3
  end
data/test/test.rb CHANGED
@@ -2,16 +2,25 @@ direc = File.dirname(__FILE__)
2
2
 
3
3
  require 'rubygems'
4
4
  require 'bacon'
5
+ require 'open4'
5
6
  require "#{direc}/../lib/method_source"
6
7
  require "#{direc}/test_helper"
7
8
 
8
9
  describe MethodSource do
9
10
 
11
+ describe "emitted warnings" do
12
+ it 'should emit no warnings' do
13
+ Open4.popen4 'ruby -I lib -rubygems -r"method_source" -W -e "exit"' do |pid,stdin,stdout,stderr|
14
+ stderr.read.empty?.should == true
15
+ end
16
+ end
17
+ end
18
+
10
19
  describe "source_location (testing 1.8 implementation)" do
11
20
  it 'should return correct source_location for a method' do
12
21
  method(:hello).source_location.first.should =~ /test_helper/
13
22
  end
14
-
23
+
15
24
  it 'should not raise for immediate instance methods' do
16
25
  [Symbol, Fixnum, TrueClass, FalseClass, NilClass].each do |immediate_class|
17
26
  lambda { immediate_class.instance_method(:to_s).source_location }.should.not.raise
@@ -34,7 +43,7 @@ describe MethodSource do
34
43
  @lambda_source = "MyLambda = lambda { :lambda }\n"
35
44
  @proc_source = "MyProc = Proc.new { :proc }\n"
36
45
  end
37
-
46
+
38
47
  it 'should define methods on Method and UnboundMethod and Proc' do
39
48
  Method.method_defined?(:source).should == true
40
49
  UnboundMethod.method_defined?(:source).should == true
@@ -57,36 +66,39 @@ describe MethodSource do
57
66
  it 'should return source for a singleton method' do
58
67
  $o.method(:hello).source.should == @hello_singleton_source
59
68
  end
60
-
61
-
69
+
70
+
62
71
  it 'should return a comment for method' do
63
72
  method(:hello).comment.should == @hello_comment
64
73
  end
65
74
 
66
- it 'should raise for C methods' do
67
- lambda { method(:puts).source }.should.raise RuntimeError
75
+
76
+ if !is_rbx?
77
+ it 'should raise for C methods' do
78
+ lambda { method(:puts).source }.should.raise RuntimeError
79
+ end
68
80
  end
69
81
  end
70
82
 
71
- if RUBY_VERSION =~ /1.9/
83
+ # if RUBY_VERSION =~ /1.9/ || is_rbx?
72
84
  describe "Lambdas and Procs" do
73
85
  it 'should return source for proc' do
74
86
  MyProc.source.should == @proc_source
75
87
  end
76
-
88
+
77
89
  it 'should return an empty string if there is no comment' do
78
90
  MyProc.comment.should == ''
79
91
  end
80
-
92
+
81
93
  it 'should return source for lambda' do
82
94
  MyLambda.source.should == @lambda_source
83
95
  end
84
-
96
+
85
97
  it 'should return comment for lambda' do
86
98
  MyLambda.comment.should == @lambda_comment
87
99
  end
88
- end
89
- end
100
+ end
101
+ # end
90
102
  describe "Comment tests" do
91
103
  before do
92
104
  @comment1 = "# a\n# b\n"
@@ -107,13 +119,13 @@ describe MethodSource do
107
119
  it "should keep empty comment lines" do
108
120
  method(:comment_test3).comment.should == @comment3
109
121
  end
110
-
122
+
111
123
  it "should ignore blank lines between comments" do
112
124
  method(:comment_test4).comment.should == @comment4
113
125
  end
114
126
 
115
127
  it "should align all comments to same indent level" do
116
128
  method(:comment_test5).comment.should == @comment5
117
- end
129
+ end
118
130
  end
119
131
  end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,7 @@
1
+ def is_rbx?
2
+ defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /rbx/
3
+ end
4
+
1
5
  module M
2
6
  def hello; :hello_module; end
3
7
  end
@@ -6,7 +10,7 @@ $o = Object.new
6
10
  def $o.hello; :hello_singleton; end
7
11
 
8
12
  # A comment for hello
9
-
13
+
10
14
  # It spans two lines and is indented by 2 spaces
11
15
  def hello; :hello; end
12
16
 
metadata CHANGED
@@ -1,12 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: method_source
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 4
8
- - 1
9
- version: 0.4.1
4
+ prerelease:
5
+ version: 0.6.0
10
6
  platform: ruby
11
7
  authors:
12
8
  - John Mair (banisterfiend)
@@ -14,8 +10,7 @@ autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
12
 
17
- date: 2011-04-11 00:00:00 +12:00
18
- default_executable:
13
+ date: 2011-06-09 00:00:00 Z
19
14
  dependencies:
20
15
  - !ruby/object:Gem::Dependency
21
16
  name: ruby_parser
@@ -25,10 +20,6 @@ dependencies:
25
20
  requirements:
26
21
  - - ">="
27
22
  - !ruby/object:Gem::Version
28
- segments:
29
- - 2
30
- - 0
31
- - 5
32
23
  version: 2.0.5
33
24
  type: :runtime
34
25
  version_requirements: *id001
@@ -40,13 +31,20 @@ dependencies:
40
31
  requirements:
41
32
  - - ">="
42
33
  - !ruby/object:Gem::Version
43
- segments:
44
- - 1
45
- - 1
46
- - 0
47
34
  version: 1.1.0
48
35
  type: :development
49
36
  version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: open4
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.0.1
46
+ type: :development
47
+ version_requirements: *id003
50
48
  description: retrieve the sourcecode for a method
51
49
  email: jrmair@gmail.com
52
50
  executables: []
@@ -56,15 +54,14 @@ extensions: []
56
54
  extra_rdoc_files: []
57
55
 
58
56
  files:
59
- - lib/method_source.rb
60
- - lib/method_source/version.rb
61
57
  - lib/method_source/source_location.rb
58
+ - lib/method_source/version.rb
59
+ - lib/method_source.rb
62
60
  - test/test.rb
63
61
  - test/test_helper.rb
64
62
  - README.markdown
65
63
  - Rakefile
66
64
  - .gemtest
67
- has_rdoc: yard
68
65
  homepage: http://banisterfiend.wordpress.com
69
66
  licenses: []
70
67
 
@@ -78,21 +75,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
78
75
  requirements:
79
76
  - - ">="
80
77
  - !ruby/object:Gem::Version
81
- segments:
82
- - 0
83
78
  version: "0"
84
79
  required_rubygems_version: !ruby/object:Gem::Requirement
85
80
  none: false
86
81
  requirements:
87
82
  - - ">="
88
83
  - !ruby/object:Gem::Version
89
- segments:
90
- - 0
91
84
  version: "0"
92
85
  requirements: []
93
86
 
94
87
  rubyforge_project:
95
- rubygems_version: 1.3.7
88
+ rubygems_version: 1.7.2
96
89
  signing_key:
97
90
  specification_version: 3
98
91
  summary: retrieve the sourcecode for a method