diff --git a/lib/method_source.rb b/lib/method_source.rb index 7d16c3b..d5b87b4 100644 --- a/lib/method_source.rb +++ b/lib/method_source.rb @@ -6,6 +6,7 @@ require "#{direc}/method_source/version" require "#{direc}/method_source/source_location" require "#{direc}/method_source/code_helpers" +require "#{direc}/method_source/irb" module MethodSource extend MethodSource::CodeHelpers @@ -49,6 +50,7 @@ def self.comment_helper(source_location, name=nil) # @return [Array] the contents of the file # @raise [SourceNotFoundError] def self.lines_for(file_name, name=nil) + return IRB.CurrentContext.source if file_name == "(irb)" @lines_for_file ||= {} @lines_for_file[file_name] ||= File.readlines(file_name) rescue Errno::ENOENT => e diff --git a/lib/method_source/irb.rb b/lib/method_source/irb.rb new file mode 100644 index 0000000..5de2fbb --- /dev/null +++ b/lib/method_source/irb.rb @@ -0,0 +1,24 @@ +# From the gem "cute_print", and before that from the gem "wrong" + +if defined? IRB + module IRB + class Context + + def source + @all_lines.join + end + + original_evaluate = instance_method(:evaluate) + + # Save every line that is evaluated. This gives a way to get + # the source when it is run in irb. + define_method :evaluate do |src, line_no| + @all_lines ||= [] + @all_lines += ["\n"] * (line_no - @all_lines.size - 1) + @all_lines += src.lines.to_a + original_evaluate.bind(self).call src, line_no + end + + end + end +end diff --git a/method_source.gemspec b/method_source.gemspec index d24b3d9..7a2602d 100644 --- a/method_source.gemspec +++ b/method_source.gemspec @@ -22,6 +22,16 @@ Gem::Specification.new do |s| if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, ["~> 1.1.0"]) s.add_development_dependency(%q, ["~> 0.9"]) + # Under some versions of Rubinius, when the tests are run with + # `bundle exec rake`, the irb tests failes with: + # rubysl-irb is not part of the bundle. Add it to Gemfile. + # This seems to be a bug in some version of Rubinius: + # https://gitter.im/rubinius/rubinius/archives/2015/04/14 + # Since this is only a development dependency, we can get away + # with the the condition. + if Object.const_defined?("RUBY_ENGINE") && RUBY_ENGINE == 'rbx' + s.add_development_dependency(%q) + end else s.add_dependency(%q, ["~> 1.1.0"]) s.add_dependency(%q, ["~> 0.9"]) diff --git a/test/test.rb b/test/test.rb index 4743a50..cb34378 100644 --- a/test/test.rb +++ b/test/test.rb @@ -2,6 +2,7 @@ require 'rubygems' require 'bacon' +require 'shellwords' require "#{direc}/../lib/method_source" require "#{direc}/test_helper" @@ -135,4 +136,21 @@ class << $o; self; end.instance_method(:hello).source.should == @hello_singleton method(:comment_test5).comment.should == @comment5 end end + + it "should work in irb" do + lib_path = File.join(File.dirname(__FILE__), "../lib") + command = [ + "irb", + "-I", lib_path, + ].shelljoin + output = IO.popen(command, "r+") do |io| + io.puts 'require "method_source"' + io.puts 'l = lambda { }' + io.puts 'puts "l = #{l.source.inspect}"' + io.close_write + io.read + end + output.should.include 'l = "l = lambda { }\n"' + end + end