I think I finally found a real bug - or, at the least, a difference in behaviour between Reline and Readline
rubyFeedback opened this issue · comments
Hey again reline-devs,
I think I finally found a bug, at the least an issue on my computer setup.
I also wrote a .rb file that can reproduce this behaviour - at the least on my machine.
So, without further ado, first the .rb file content that shows the behaviour - you should
be able to easily copy/paste it, I made sure that it works standalone (although you
may need the readline gem and perhaps the reline gem installed to test its
behaviour):
require 'reline'
require 'readline'
RED = "\u001b[31m"
RESET = "\u001b[0m"
alias e puts
alias ee print
# Determine the mode - change the following between the
# three symbols :reline, :readline and :stdin.
USE_THIS_MODE = :stdin # :readline # :reline
def show_the_prompt
ee Dir.pwd+'/'
end
loop {
show_the_prompt
case USE_THIS_MODE
when :stdin
user_input = $stdin.gets.chomp
when :reline
user_input = Reline.readline('',true)
when :readline
user_input = Readline.readline('',true)
e
end
case user_input
when 'q','exit'
break
else
ee RED+user_input+RESET
end
}
Alright.
So, how to use this? The CONSTANT called USE_THIS_MODE can be
used to toggle between three modes:
:reline
:readline
:stdin
By default it will use :stdin. This is the normal behaviour. Please run
that script - you will see that on pressing enter, a new line is shown,
and then the current working directory is displayed via the method
call show_the_prompt().
Now, please try it again, but change the value of the constant from
:stdin to :readline. Then run the file again.
The behaviour between :readline and :stdin is the same. The only
difference as far as I can tell is that via readline we get additionally
the input history, so we can access it via the arrow-keys on the
keyboard. (We could also use tab completion, but for this demo
I only wanted to showcase the issue at hand, not to get overly
fancy.)
Now switch that constant to :reline please. When I do so and run
it, I get a different behaviour: I don't get any output. But, oddly
enough, when I hit the enter key multiple times, and do so
quickly, then sometimes I suddenly have input. To me it seems
as if Reline is doing some buffering internally and that leads
to awkward behaviour. When I use Readline then that behaviour
does not show up, so either this is a bug in Reline, or at the least
another incompatibility. It is a bit confusing and I think for the time
being I have to prefer Readline.
The API I use is:
Reline.readline('',true)
Which I do for Readline too:
Readline.readline('',true)
Not sure if that causes any difference in behaviour or another method
should be used. If you folks can not see any difference behaviour if
you try all three variants then perhaps something else is messed up
on my system - but it can not be completely messed up, because
$stdin and Readline work just fine, whereas Reline does not, so I
suspect that Reline is doing something that leads to swallowing
input or something like that. Or perhaps it is related to print(), I
am not sure.
Can anyone try the above .rb script in each of the three variants
and then see if there is a difference? If there is not then perhaps
my computer is messed up.
Readline doesn't clear current line so you can do something like this
require 'readline'
print 'pro'
sleep 1
Readline.readline('mpt>')
# prompt> (looks like prompt is `prompt>` but it has problem described below)
In Reline, you can see pro
is displayed only 1 sec, Reline clears current line and prompt will be mpt>
require 'reline'
print 'pro'
sleep 1
Reline.readline('mpt>')
# mpt>
I prefer Reline's behavior because Readline's behavior have problem
require 'readline'
print 'pro'
input = Readline.readline('mpt>')
p input: input
# press `helloworld [\C-a] ! [enter]` will get
# prom!helloworldld ← prompt and input is displayed broken
# {:input=>"!helloworld"} ← input is correct
These kind of Readline's behavior (maybe a bug, unexpected usage, undefined behavior or something) might be fixed or changed in the future and will depend on Readline's version.
IMO I don't think Reline should follow it.