`show_source` can't find some sources defined in the session
amomchilov opened this issue · 1 comments
Description
irb
can find the source of a method defined during the repl session, but not its parent class.
irb(main):001* class Foo
irb(main):002* def x = "Hello, world!"
irb(main):003> end
=> :x
irb(main):004> Foo.instance_method(:x).source_location
=> ["(irb)", 2]
irb(main):005> show_source Foo#x # Works ✅
From: (irb):2
def x = "Hello, world!"
=> nil
irb(main):006> show_source Foo # Not found ❌
Error: Couldn't locate a definition for Foo
=> nil
A similar thing happens if you execute a script from standard input
$ ruby
class Foo
def x = "Hello, world!"
end
binding.irb
< I press ctrl-d to send EOF >
irb(main):001> Foo.instance_method(:x).source_location
=> ["-", 2]
irb(main):002> show_source Foo#x # Not found ❌
Error: Couldn't locate a definition for Foo#x # Not found ❌
=> nil
irb(main):003> show_source Foo # Not found ❌
Error: Couldn't locate a definition for Foo # Not found ❌
=> nil
Notes
This does work if running from a saved script:
# example_script.rb
class Foo
def x = "Hello, world!"
end
binding.irb
ruby ./example_script.rb
From: ./example_script.rb @ line 5 :
1: class Foo
2: def x = "Hello, world!"
3: end
4:
=> 5: binding.irb
irb(main):001> show_source Foo
From: ./example_script.rb:1
class Foo
def x = "Hello, world!"
end
nil
Result of irb_info
irb(main):001> irb_info
Ruby version: 3.3.0
IRB version: irb 1.13.1 (2024-05-05)
InputMethod: RelineInputMethod with Reline 0.5.8
Completion: Autocomplete, RegexpCompletor
RUBY_PLATFORM: x86_64-linux
LANG env: en_US.UTF-8
LC_ALL env: en_US.UTF-8
East Asian Ambiguous Width: 1
## Terminal Emulator
What's your terminal emulator? **iTerm 2.**
## Setting Files
Are you using `~/.irbrc` and `~/.inputrc`? **Nope.**
If the source file exist, source is available.
Even if the file does not exist, IRB can show method source defined in IRB because RubyVM::AbstractSyntaxTree.keep_script_lines
is enabled in IRB session.
if you execute a script from standard input
It is impossible now. keep_script_lines can't be enabled before evaluating script from standard input.
show_source Foo # Not found
Constant source is not available from AST.
We need to add an identifier to the source file '(irb)'
like '(irb[session_id])'
and store all input lines, which I avoid and use keep_script_lines = true
instead in #862.
$ ruby -e "loop{binding.irb}"
irb(main):001> A=1 # defined in line 1
irb(main):002> exit
irb(main):001> B=1 # also defined in line 1. source file string should be different to distinguish B from A
irb(main):002> Object.const_source_location(:A) == Object.const_source_location(:B)
#=> true # should be false to implement constant source defined in irb session