Interactive Processing of print

D

dmatrix00d

For example, I have a python program that does

print "hello"
time.sleep(10)
print "world"

and i want to print this in ruby

"hello foo"
(wait 10 seconds)
"world foo"

I tried :

IO.popen("python example.py") do |p|
p.each do |line|
puts line + "foo"
end
end

and it does everything except , it waits the 10 seconds before it
begins processing so it is not interactive
 
T

ts

d> and it does everything except , it waits the 10 seconds before it
d> begins processing so it is not interactive

Well the problem is in the P language, fatally :)

Seriously, with these scripts

moulon% cat b.rb
#!/usr/bin/ruby
IO.popen("ruby c.rb") do |p|
p.each do |line|
puts line + "foo"
end
end
moulon%

moulon% cat c.rb
#!/usr/bin/ruby
puts "hello"
sleep(10)
puts "word"
moulon%

You'll have the same result, but if you change the script c.rb to add
'stdout.sync = true' it will work as expected

moulon% cat c.rb
#!/usr/bin/ruby
$stdout.sync = true
puts "hello"
sleep(10)
puts "word"
moulon%

this mean that, in your case, the problem is with the python script not
with ruby.
 
E

Erich Lin

The example was just an example. I mainly want to be able to run any
program (not just a python program), and still intercept the print
statements and do something with them.

Thanks,

Sorry for the confusion
 
E

Erich Lin

The example was just an example. I mainly want to be able to run any
program (not just a python program), and still intercept the print
statements and do something with them.

Thanks,

Sorry for the confusion
 
T

ts

E> The example was just an example. I mainly want to be able to run any
E> program (not just a python program), and still intercept the print
E> statements and do something with them.

You can't intercept the print statements if the program don't flush the
data. This is why I've added the line

$stdout.sync = true

to make work, like you expect, the script, because with this line, ruby
will flush the data after a \n

i.e when you use a print statement, the data is just put in a buffer and
this is only when the buffer is flushed that it's made available to
others programs.
 
E

Erich Lin

this might be a stupid reply, but how come

system ("python example.py) works?

it prints

hello
(wait 10 seconds)
world.

i just want the effects of that, but do something with that print
statement

thanks
 
T

ts

E> this might be a stupid reply, but how come
E> system ("python example.py) works?

Try this

python example.py

it must do what you expect (i.e it print 'hello' wait 10 seconds). Then
try

python example.py | cat

and see what it do.
 
E

Erich Lin

just doing python example.py ? how?
with backqutoes?

and cat assumes that this program will be run on *nix, which it may not
be.

and even if python example.py | cat using what?
 
T

ts

E> just doing python example.py ? how?
E> with backqutoes?

no, no. just running interactively

python example.py

E> and cat assumes that this program will be run on *nix, which it may not
E> be.

yes, un*x system. Probably the command is `type' on a dos system, I don't know

E> and even if python example.py | cat using what?

on an un*x system if you execute

python example.py | cat

you'll wait 10 secondes before seeing the output 'hello' 'world' like for
your ruby program.

This is because I've created a pipe (`|') that you have this
result. When you use #popen this is like if you create a pipe.
 
E

Erich Lin

I understand what you mean.
is there a way around that is my question, because system lets you get
around that, but you can't modify it, which i guess is what your first
example is saying.

i remember a post where someone said you can do this with popen, but it
won't work for all cases. i guess this is one of them. so how would you
do it for this case?
 
T

ts

E> i remember a post where someone said you can do this with popen, but it
E> won't work for all cases. i guess this is one of them. so how would you
E> do it for this case?

The only way to make it work is to modif example.py (or any program that
you want to run). If you can't do it, you will not be able to do what you
want.
 
E

Erich Lin

modify in what way?
E> i remember a post where someone said you can do this with popen, but it
E> won't work for all cases. i guess this is one of them. so how would you
E> do it for this case?

The only way to make it work is to modif example.py (or any program that
you want to run). If you can't do it, you will not be able to do what you
want.
 
K

Kenosis

I believe they mean to have the program in question flush its output
buffer, if that's possible in the language in question.

Ken
 
E

Erich Lin

Below is the old post that explains what I mean. However, it doesn't
work for my case. Is there a way to adopt it to work for my case?

Here it is:
You won't be able to use backquotes here, because backquotes wait for
all the output to appear before returning (as that's what they are
intended for).

Instead, you can open a pipe to the child process and read it's output
interactively.

IO.popen(command) do |p|
p.each do |line|
puts line
end
end

However, there's a further wrinkle. Often, programs that produce output
line-by-line when you run them interactively change their behavior
when run as a subprocess talking to a pipe. For example, here's a
simple Ruby program:

5.times do
puts "hello"
sleep 1
end

Run it form the command line, and it does what you expect. However,
run it as the command in the popen example above, and you won't see
any output until it finishes. You need to change it to

$stdout.sync = true
5.times do
puts "hello"
sleep 1
end

To get it to write the output as it's produced.

Regards

Dave

Btw , what do you mean kenosis
 
K

Kenosis

What I meant was, if the command being run is buffering its output and
doesn't have an equiv. to stdout.sync=true then the command would need
to flush its output buffer at well chosen points to allow incremental
"delivery" of its output. I think we're more or less all saying the
same thing here, no?

Ken
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,206
Messages
2,571,074
Members
47,679
Latest member
Justforamoment

Latest Threads

Top