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.