1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

irb.rb: show source around binding.irb on start

[Feature #14124] [ruby-dev:50319] [close GH-1764]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60888 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
k0kubun 2017-11-24 03:53:27 +00:00
parent f8523d35bf
commit 106c9883e1
4 changed files with 105 additions and 1 deletions

3
NEWS
View file

@ -158,6 +158,9 @@ with all sufficient information, see the ChangeLog file or Redmine
* IPAddr now rejects invalid address mask. [Bug #13399]
* IPAddr#ipv4_compat and #ipv4_compat? are deprecated. [Bug #13769]
* IRB
* Show source around `binding.irb` on session start
* Net::HTTP
* Add more HTTP status classes

View file

@ -706,6 +706,8 @@ class Binding
undef irb if method_defined?(:irb)
def irb
IRB.setup(eval("__FILE__"))
IRB::Irb.new(IRB::WorkSpace.new(self)).run(IRB.conf)
workspace = IRB::WorkSpace.new(self)
STDOUT.print(workspace.code_around_binding)
IRB::Irb.new(workspace).run(IRB.conf)
end
end

View file

@ -107,6 +107,27 @@ EOF
bt
end
def code_around_binding
file = @binding.eval('__FILE__')
pos = @binding.eval('__LINE__') - 1
return nil unless File.exist?(file)
if defined?(SCRIPT_LINES__) && SCRIPT_LINES__.key?(file)
lines = SCRIPT_LINES__[file].split(/^/)
else
lines = File.readlines(file)
end
start_pos = [pos - 5, 0].max
end_pos = [pos + 5, lines.size - 1].min
body = (start_pos..end_pos).map do |current_pos|
lineno = "%#{end_pos.to_s.length}d" % (current_pos + 1)
" #{pos == current_pos ? '=>' : ' '} #{lineno}: #{lines[current_pos]}"
end.join
"\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}\n"
end
def IRB.delete_caller
end
end

View file

@ -0,0 +1,78 @@
# frozen_string_literal: false
require 'test/unit'
require 'tempfile'
require 'irb/workspace'
module TestIRB
class TestWorkSpace < Test::Unit::TestCase
def test_code_around_bindinig
Tempfile.create do |f|
code = <<~RUBY
# 1
# 2
IRB::WorkSpace.new(binding) # 3
# 4
# 5
RUBY
f.print(code)
f.close
workspace = eval(code, binding, f.path)
assert_equal(<<~EOS, workspace.code_around_binding)
From: #{f.path} @ line 3 :
1: # 1
2: # 2
=> 3: IRB::WorkSpace.new(binding) # 3
4: # 4
5: # 5
EOS
end
end
def test_code_around_bindinig_with_script_lines__
with_script_lines do |script_lines|
Tempfile.create do |f|
code = "IRB::WorkSpace.new(binding)\n"
script_lines[f.path] = code
workspace = eval(code, binding, f.path)
assert_equal(<<~EOS, workspace.code_around_binding)
From: #{f.path} @ line 1 :
=> 1: IRB::WorkSpace.new(binding)
EOS
end
end
end
def test_code_around_bindinig_on_irb
workspace = eval("IRB::WorkSpace.new(binding)", binding, "(irb)")
assert_equal(nil, workspace.code_around_binding)
end
private
def with_script_lines
script_lines = nil
debug_lines = {}
Object.class_eval do
if defined?(SCRIPT_LINES__)
script_lines = SCRIPT_LINES__
remove_const :SCRIPT_LINES__
end
const_set(:SCRIPT_LINES__, debug_lines)
end
yield debug_lines
ensure
Object.class_eval do
remove_const :SCRIPT_LINES__
const_set(:SCRIPT_LINES__, script_lines) if script_lines
end
end
end
end