Ruby help - controlling stdin, stdout

OK, I have a main Ruby program, which i would like to be able to execute
other ruby programs from. I would like the main ruby program to simulate
the actions of a command prompt (i’m using windows) i.e. i would like
the main program to print out output from the running program and to
know when input is needed.

I have the following:

IO.popen(“ruby other_program”, “r+”) do |f|

i can read and write to “other_program” here, however i want the main

program to be prompted when the “other_program” is waiting for input

So, i think i need to override the STDIN and STOUT of the process in the
“other_program”, however i’m not sure how to do this, can anyone help
please?

There is a good chance that you are taking the wrong approach to
solving this problem. You should give more details about what you are
trying to accomplish.

greg wrote:

There is a good chance that you are taking the wrong approach to
solving this problem. You should give more details about what you are
trying to accomplish.

I am creating a rails application that allows users to create ruby
programs and save them to file. I now need to be able to run the users
programs. I am able to run the user programs and read the output that is
displayed from the program, however when the user program blocks waiting
for input (i.e. ‘gets’ is called) I need to be able to signal to the
rails program before blocking so that something can be written to the
STDIN buffer for the user program to read.

I have access to the user programs so could input some code into that,
which would take over the STDIN and STDOUT of the process, however i am
not sure how to do this… and I am using windows

any ideas?

watch out for security issues… there is no a sandbox in the latest
1.9 source …

Can’t you just write to the program’s STDIN before it calls gets
anyways?

otherwise, you can monitor STDOUT for some kind of signal

alias_method :gets :old_gets
def gets
puts “WAITING_FOR_INPUT”
old_gets
end

I have not tried to do signal trapping, but instead of checking for a
special sequence on STDOUT you could try to send signals back and
forth.

This could be done by inserting a require statement, or by using a
launcher program.
Instead of creating a separate ruby process, you can run the other
programs from a launcher. In the launcher program just put
load #{user_program}
In the launcher program you can also modify $LOAD_PATH and ENV[‘PATH’]
if you need.
One problem you may encounter with this approach is that the call stack
will have one more entry than expected- this could break things that do
not expect another level in caller(), or if the user program makes a
check like if $0 == FILE before executing.