On Thu, 28 Sep 2006, greg wrote:

> so the answer is that I must rely on the user to indicate what they are
> doing.  And if the user gives a '-' and there is no pipe than the program
> will hang.  This is not so bad, but I was just hoping there was a better
> way.  I think though there should be some way to avoid this.  I don't know
> if there is lower level information here that we cannot extract in ruby, but
> I also wonder if there is a way to avoid this in Ruby: for example read from
> STDIN for just one second, and then determine if any data was read.  I think
> though in UNIX that when you pipe programs from the shell that all the
> programs are opened up immediately, so even this could have problems.

it's so much more terrible than you realize.  you can tell if there is data
ready on stdin:

   harp:~ > cat a.rb
   require 'io/wait'

   if STDIN.ready?  # then it either has data or is at eof
     buf = STDIN.read
     puts buf
   else
     puts 'no pipe'
   end


   harp:~ > ruby -e' puts 42 ' | ruby a.rb
   "42"


now, you may think that's great.  but run it a few times.

   ...
   ...
   ...


   harp:~ > ruby -e' puts 42 ' | ruby a.rb
   no pipe


see, it's a race condition.  __maybe__ the shell has setup the two processes
and stdin of one is connected to the stdout of the other, then again maybe
it's not quite there yet.  io is pain.  from now on i'm writing only
functional programs with no input or output.

any sort of non-blocking read on STDIN will do the same thing.  that's why all
well behaved programs do indeed block reading stdin when none is ready - it's
the only safe thing to do.  btw - stevens book is amazing...

i just use '-', or simply always read from STDIN, and then sleep at night ;-)

-a
-- 
in order to be effective truth must penetrate like an arrow - and that is
likely to hurt. -- wei wu wei