If using a screenreader like VoiceOver for the Mac and you use Reline.readmultiline , for example in a loop , say in a REPL, and you output a string without terminating the line with a newline, funny things happen to your screenreader. Like, it no longer outputs the characters you type.
This can be easily demonstrated using Docker and 2 images: ruby:2.6 and ruby:3.2 In ruby:2.6 and before, the same program 'irb', Ruby's own REPL does not experience this problem. But in Ruby 2.7 and above, irb was changed to use the new Reline module instead of the venerable Readline, a wrapper around the venerable GNU readline library.
This probably does not seem noticable to a sighted user, but for VoiceOver users, it does something nasty to the Terminal (or to VoiceOver itself).
The following screen captures might look exactly the same to you, but trust me they are radically different. in audio output of the VoiceOver screen reader.
docker run --rm -it ruby:2.6 bash
root@0ae8700a82b6:/# irb
irb(main):001:0> print('foo')
foo=> nil
irb(main):002:0>
root@0ae8700a82b6:/#
exit
$# fff
$ # The above "# fff" echos each character normally
$ docker run --rm -it ruby:3.2 bash
root@c6c4f0bf7564:/# irb
irb(main):001:0> print('foo')
foo=> nil
irb(main):002:0>
root@c6c4f0bf7564:/#
exit
$ # fff
Note: that I typed 'fff' after pressing Control+d to exit the Docker running ruby:3.2 container. All I heard was: space space space
One way to fix this is by typing 'reset' in the terminal. This seems to clear this up.
My next step in the investigation is too run 'strace' and dump the calls to write on the FD #1 file descriptor. Then, diff the output from both Docker sessions. I want to have someone else attempt this and see if the same or similar results occur to them.
Because 'reset' clears up the problem, I can try and D/L another Terminal emulator and run the test again.
You should be on a Mac running MacOS Catalina or later. Press/toggle VoiceOver by holding down the command key and pressing F5. You should have Docker installed, or ssh into a machine that does. (That is how I tested it)
For completeness, I ran the test on a Debian version Bullseye (11, IIRC)
The Docker version is: Docker version 23.0.0, build e92dd87
As far as VoiceOver goes: Make sure to have all characters output one at a time and all punctuation symbols output. When finished, re-press Command plus F5 again to turn off VoiceOver
Update: Ran strace on both Ruby versions: 2.6.2 and 3.1.2
Then mv'd s.out to f2.out and f3.out
Then extracted only the hex strings:
``bash
egrep -n -o '"[^"]"' f2.out > f2.str
Then captured the final difference block, which starts around line 695
That is captured here:
695,698c695,699
< 696:"\x1b\x5b\x31\x42"
< 697:"\x1b\x5b\x31\x47"
< 698:"\x1b\x5b\x4b"
< 699:"\x1b\x5b\x31\x47"
Summary:
There is a single ANSI escape sequence that is extra being sent to the terminal
by Ruby's Reline module that is not being sent by the old readline based on GNU readline.
Not sure what this has to do with the messing of the MacOS VoiceOver screenreader and the Terminal.app.
But it does, and the only to resolve is to type 'reset' (which you only
hear "space space space space space space" and have to trust you are typing it correctly.