In message "[ruby-talk:01318] Bug in Kernel.open (I think)"
    on 00/02/12, Dave Thomas <Dave / thomases.com> writes:

|You recently changed Kernel.open so it would take a block in the pipe
|form. Unfortunately, I think now it _has_ to take a block:

You are right, and your fix should be OK.

But I've not decided yet about the behavior.  I cannot explain good,
but I'll try anyway.

usual (non-pipe) `open' uses block to ensure closing.

  open(path) {|f| ..work on f..}

`open' with pipe to self, i.e. `open("|-")', without block, returns IO
for parent process, and nil for child process.

And the new behavior for `open("|-")' with block is to give opened
port to block (nil for child process).  Thus you should write

   open("|-") {|f| 
     if f == nil then ..child process ..
     else ..parent process.. end
   }

The problems are:

  * backward incompatibility

    Old behavior executes block only on parent process, it did not
    require nil check in block.  The new bahavior broke some scripts.
    I received a trouble report about this behavior change.

  * unavoidable conditional

    By new behavior, nil check in the block is must.  It's not as easy
    as it should be, I think.  For example, `fork' uses block to
    execute under child process.

      fork { p "in child" }

    No conditinal needed, easy to write&read.  Oh, I wish I can say

      open("|-"){..child..}{..parent..}

    Or, maybe

     open("|-", proc{..child..}){parent}

    The latter is syntactically possible.

What do you think about this?
							matz.