On Jun 8, 2009, at 9:32 PM, Nicolas Cellier wrote:
There are better examples where I want Exceptions, so I'd like the choice to be in programmers hands. - 1) Raising an EndOfStream Exception (and not a Notification as I suggested) should be optional - 2) The Exception should not have a default action.
To add emphasis: it can't have a default action or it is not doing its job.
The simple thing to do is to add an endOfStreamAction instanceVariable to Stream or ReadStream. If a read past end is attempted, then ^endOfStreamAction value.
nil value = nil, so letting this inst var uninitialized will lead to backward compatibility (at minimal cost concerning efficieny!). filling the inst var with a block comes to mind immediately, and among natural choice is: Stream>>willSignalEndOfStream self endOfStreamAction: [EndOfStream signal]
There might be more work for Stream wrappers, but that sounds a cheap and efficient idea to reconcile both worlds.
What will protect above code example from an internal low level EndOfStream? Nothing, but the fact that programmers using explicitely #willSignalEndOfStream will know what they do! Either they will protect with a handling block, or advertise enough that the code might generate spurious EndOfStream on malformed inputs...
I hesitate to call the exceptions spurious; in situations where they would be described as such, I generally would use #nextAvailable: and write code that won't blow up. Exceptions do a very important job: they carry information from the point of detection of a problem to a place (often far removed on the stack) where a corrective action can be reasonably applied. To (attempt) to paraphrase your idea, you are proposing to remove the default action from EndOfStream, replacing that blunting of exceptions with an uninitialized endOfStreamAction instance variable that defalts to the same behavior, and can be set to ensure raising of exceptions. Fair? This is certainly worth a try. For my part, the cost would be I need to ensure that I set the exception behavior on every stream I create vs. ensuring I use a different set of methods. It's probably no worse, and maybe easier to enforce. I will generally hide ReadStream on: behind a helper, #readStream, so I could just as easily use #readStreamRobust to create the stream and activate exceptions. Sorry to press this so hard, but I cannot afford to have things breaking w/o telling me. At best, that wastes time to track down mysterious failures, and worse, it can be dangerous. It's not unlike the practice of building electronic enclosures with lots of exposed grounded metal. It took me a while to gain comfort with it, but the idea is that if a wire comes loose, it hits ground, pulls a breaker, and goes into a safe mode and gets attention as a side effect. Bill