irb icon indicating copy to clipboard operation
irb copied to clipboard

Readline.readline("question") compatibility is broken, question is not shown

Open stillhart opened this issue 1 year ago • 1 comments

Description

I expect to be able to use Readline.readline("answer me pls> ") within irb. Right now it does read my answer but the answer me pls> gets lost instead of sent to STDOUT. I can only reproduce the problem in Ruby 3.3.0. I am unable to reproduce the problem in Ruby 3.2.2 using the latest gems.

I am not 100% certain whether it is an irb, readline or reline problem but it does not happen outside of irb.

Reality

irb(main):001> require 'readline'
=> true
irb(main):002> Readline.readline('answer me pls> ')
irb(main):003>  yes
=> "yes"
# Note, the 'answer me pls> ' is missing

Expectation

irb(main):001> require 'readline'
=> true
irb(main):002> Readline.readline('answer me pls> ')
answer me pls> ok
=> "ok"

without irb

ruby -rreadline -e "Readline.readline('answer me pls> ')"
answer me pls> '

Result of irb_info

Ruby version: 3.3.0
IRB version: irb 1.11.1 (2024-01-08)
InputMethod: RelineInputMethod with Reline 0.4.2
Completion: Autocomplete, RegexpCompletor
.irbrc path: /home/stillhart/.irbrc
RUBY_PLATFORM: x86_64-linux
LANG env: en_US.UTF-8
LC_ALL env: en_US.UTF-8
East Asian Ambiguous Width: 1
gem list irb reline readline
*** LOCAL GEMS ***
irb (1.11.2, 1.11.1, default: 1.11.0, 1.10.1, 1.7.4)
*** LOCAL GEMS ***
reline (0.4.2, default: 0.4.1, 0.3.8)
*** LOCAL GEMS ***
readline (default: 0.0.4)

Terminal Emulator

Vscode and iterm

Setting Files

~/.irbrc
IRB.conf[:SAVE_HISTORY] = 1000
IRB.conf[:HISTORY_FILE] = "~/.irb-history"

OS

Happens both on Redhat7 and MacOS Sonoma

Working versions

Switching to older ruby versions such as 3.2.2 or 3.0.5 solves the problem for me, but that might be because of older dependencies.

Ruby 3.2.2 version

stillhart$ chruby 3.2.2
stillhart$ irb
irb(main):001> require 'readline'
=> true
irb(main):002> Readline.readline("answer me pls> ")
answer me pls> 
=> ""
irb(main):003> irb_info
Ruby version: 3.2.2
IRB version: irb 1.11.2 (2024-02-07)
InputMethod: RelineInputMethod with Reline 0.4.2
Completion: Autocomplete, RegexpCompletor
.irbrc path: /home/taastfa4/.irbrc
RUBY_PLATFORM: x86_64-linux
LANG env: en_US.UTF-8
LC_ALL env: en_US.UTF-8
East Asian Ambiguous Width: 1
=> nil
irb(main):004> exit
stillhart$ gem list irb reline readline

*** LOCAL GEMS ***
airbrussh (1.4.2, 1.4.1, 1.3.1)
hirb (0.7.3)
irb (1.11.2, 1.11.1, 1.11.0, 1.10.1, 1.10.0, 1.9.1, 1.8.3, 1.8.1, 1.8.0, 1.7.4, 1.7.1, 1.7.0, 1.6.4, default: 1.6.2)
*** LOCAL GEMS ***
reline (0.4.2, 0.4.1, 0.4.0, 0.3.9, 0.3.8, 0.3.7, 0.3.5, 0.3.3, default: 0.3.2)
*** LOCAL GEMS ***
readline (0.0.4, default: 0.0.3)
readline-ext (0.2.0, default: 0.1.5)

There is a chance that something is weird in my setup. I am happy to close this if it is not reproducible.

stillhart avatar Feb 09 '24 10:02 stillhart

Strange. It works for me.

https://i.imgur.com/Y8JCfy9.png

Don't mind the messiness above, I just wanted to test the result and for me it is displayed the prompt. As that is the first argument to Readline.readline().

You showed that this works without irb, so we know this does work, so the question then is why irb does not show it. My irb shows it though. I am using Linux, but you said it also happens on redhat 7, which I assume is Linux.

That's a weird error. Perhaps something tampers with buffering?

Perhaps tompng can show some code to find out how to test this behaviour of irb but from within a .rb file. Then you can perhaps narrow this down. Evidently there must be some reason for that behaviour but I am not sure what it is or should be; reline should not interfere here since Readline.readline() is a specific call to Readline, not to reline.

rubyFeedback avatar Feb 24 '24 04:02 rubyFeedback

The behavior is improved in Reline >= 0.5.3.

irb(main):001> require 'readline'
irb(main):002> Readline.readline("answer me pls> ")
answer me pls> 

Ruby 3.3 does not bundle readline-ext gem. When readline-ext is not installed, require 'readline' loads 'reline' and sets Readline = Reline so the configuration are completely shared between constant Readline and constant Reline.

require 'readline-ext' #=> LoadError
require 'readline' # loads reline
Readline.__id__ == Reline.__id__
#=> true

Although reline >= 0.5.3 fixed multiline-mode prompt applied to singleline-mode prompt problem, IRB's colorizing and autocompletion configurations are still applied to Reline.readline('>') and Readline.readline('>').

Maybe related to https://github.com/ruby/reline/issues/473 (multi instancing of Reline, not planned)

Workaround is to install readline-ext or add a monkey-patch-ish multi instancing of Reline like:

Readline = Reline.dup; Readline.instance_variable_set(:@core, nil) # might not work in the future

tompng avatar Aug 13 '24 19:08 tompng