method_source 0.4.1 → 0.6.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.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