Skip to content

Commit fd49135

Browse files
authored
Allow show_source for private methods (#589)
* Allow `show_source` for private methods Fix #577 * Pend tests on TruffleRuby It seems `eval(..., __LINE__ + 1)` does not work. Other similar tests are also pended on TruffleRuby, so I think it is acceptable. * Use `private_method_defined?` instead of `defined?`
1 parent e9c6c96 commit fd49135

2 files changed

Lines changed: 45 additions & 3 deletions

File tree

lib/irb/cmd/show_source.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,14 @@ def find_source(str, irb_context)
3131
when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
3232
owner = eval(Regexp.last_match[:owner], irb_context.workspace.binding)
3333
method = Regexp.last_match[:method]
34-
if owner.respond_to?(:instance_method) && owner.instance_methods.include?(method.to_sym)
35-
file, line = owner.instance_method(method).source_location
34+
if owner.respond_to?(:instance_method)
35+
methods = owner.instance_methods + owner.private_instance_methods
36+
file, line = owner.instance_method(method).source_location if methods.include?(method.to_sym)
3637
end
3738
when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
3839
receiver = eval(Regexp.last_match[:receiver] || 'self', irb_context.workspace.binding)
3940
method = Regexp.last_match[:method]
40-
file, line = receiver.method(method).source_location if receiver.respond_to?(method)
41+
file, line = receiver.method(method).source_location if receiver.respond_to?(method, true)
4142
end
4243
if file && line
4344
Source.new(file: file, first_line: line, last_line: find_end(file, line, irb_context))

test/irb/test_cmd.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,47 @@ def show_source_test_method
488488
assert_empty err
489489
assert_include(out, code)
490490
end
491+
492+
def test_show_source_private_instance
493+
pend if RUBY_ENGINE == 'truffleruby'
494+
eval(code = <<-EOS, binding, __FILE__, __LINE__ + 1)
495+
class PrivateInstanceTest
496+
private def show_source_test_method
497+
unless true
498+
end
499+
end unless private_method_defined?(:show_source_test_method)
500+
end
501+
EOS
502+
503+
out, err = execute_lines(
504+
"show_source '#{self.class.name}::PrivateInstanceTest#show_source_test_method'\n",
505+
)
506+
507+
assert_empty err
508+
assert_include(out, code.lines[1..-2].join)
509+
end
510+
511+
512+
def test_show_source_private
513+
pend if RUBY_ENGINE == 'truffleruby'
514+
eval(code = <<-EOS, binding, __FILE__, __LINE__ + 1)
515+
class PrivateTest
516+
private def show_source_test_method
517+
unless true
518+
end
519+
end unless private_method_defined?(:show_source_test_method)
520+
end
521+
522+
Instance = PrivateTest.new unless defined?(Instance)
523+
EOS
524+
525+
out, err = execute_lines(
526+
"show_source '#{self.class.name}::Instance.show_source_test_method'\n",
527+
)
528+
529+
assert_empty err
530+
assert_include(out, code.lines[1..-4].join)
531+
end
491532
end
492533

493534
class WorkspaceCommandTestCase < CommandTestCase

0 commit comments

Comments
 (0)