Do you have tips for driving IRB as a background process through STDIN and writing outputs to a file?
I basically want to automate some tutorials that include showing how things should look in the irb REPL including the prompts and interface. But as soon as I run it without a TTY the styles all change and I’m not sure if there’s a combination of flags/settings to get them looking the same again.
Basically trying to get these outputs to match closer: https://gist.github.com/schneems/88223a7df82795922fdc1e8e1b47bfc0
@Schneems what comes to mind is doing this within ruby, I believe IRB “is just a class”, so I’d imagine you can write code to coordinate this from within the process.
@eljojo that’s a very unique solution. I’ve not considered it before.
@Schneems been playing with a gist for the past hour. I managed to get the input to work well, but I think now I may need to override `$stdout` https://gist.github.com/eljojo/ddb1257886a5267eab6620d493f61f98
@Schneems I just updated the gist! managed to get it to output `"irb(main):001> 1 + 1\n=> 2\n\n"` into a string
@Schneems haven’t done this myself, but I think you want to create a pty and use that to drive irb. Also maybe have a look at Expect, which is designed to do this sort of thing
@sstephenson I did that before a long time ago https://github.com/schneems/repl_runner/blob/master/lib/repl_runner/pty_party.rb I think if I moved the reading to a thread and stopped caring if it hung would make things easier.
I also ran into issues where some systems didn’t support PTY in Ruby. IIRC Heroku dynos would support it for a few years. I don’t remember why or if it’s been fixed.
I wish I knew more about the distinction between a PTY and spawning a plain ole process.
@Schneems you sniped me lol. Here’s an expect script that evaluates each argument passed to it with irb:
#!/usr/bin/env expect -f
set prompt "irb.*?> "
spawn -noecho irb --inf-ruby-mode
foreach line $argv {
expect -re $prompt
send "$line\n"
}
expect -re $prompt
———
% ./irb.exp 1+1 "puts 'hi'"
irb(main):001:0> 1+1
2
irb(main):002:0> puts 'hi'
hi
nil
irb(main):003:0>
%
@Schneems just re-read your original toot. Replace `foreach line $argv` with `while {[gets stdin line] != -1}` to read lines from stdin instead
@Schneems also ran into this when trying to record animated SVGs of terminal sessions to show off the `ronin irb` command. Reline outputted unusual ANSI control characters to move the cursor around, which confused `termtosvg`.
If all you want to do is record the input and output, sans the drop-down menu or auto-complete, you can code your own crude REPL which reads input from a text file, "types" each character with some random jitter, evaluates it using `eval()`, and prints the result.
@postmodern I am writing Heroku docs and I want the output to match what customers will see as close as possible via https://github.com/zombocom/rundoc
Your suggestion is a good one, it’s how I drove my tests for background stdin_write. But I don’t want to have to track and sync output styles manually.
I know “script” terminal command is one option for faking a TTY. But the arguments differ between Mac and Linux and that’s important that it works on both for me.
@Schneems I tried to do this in Ruby but it doesn't let you redirect I/O in child processes to arbitrary `IO` objects and I can never remember how to use `popen`. So I wrote it in Crystal.
If you use this, you would just write your script inside the `spawn` block.
I don't know how to get rid of the "Switch to inspect mode" in the output, though. Specifying the `--inspect` option broke things.
https://gist.github.com/jgaskins/61908a4ec3e393117be3075633465e80
@Schneems Could you use a Jupyter notebook with a Ruby kernel?