Nicolas, Adding #nextAvailable: hurts nothing, but changing #next: (and #next too) will break existing code. In VW, it is only #next that has the silent failure trap, and while Cincom was willing to consider a change, they ultimately declined to make it. I am convinced that Dolphin gets it right, but I would be surprised to see us adopt its behavior. I would be thrilled if we did so, but doubt it will happen. Failing such breaking changes, I need to create a way to have my code work, which is why I started adding my own methods. Your pluggable exception/defaultAction idea is worth a shot. Some simple testing should show whether it can preserve current behavior and throw exceptions, respectively. I think I heard Stef as much as say he would support it if it does serve both masters. Stef? Bill -----Original Message----- From: pharo-project-bounces@lists.gforge.inria.fr [mailto:pharo-project-bounces@lists.gforge.inria.fr] On Behalf Of Nicolas Cellier Sent: Tuesday, June 09, 2009 2:34 AM To: Pharo-project@lists.gforge.inria.fr Subject: Re: [Pharo-project] About EndOfStream notification [was Streams - #nextLine] Bill, What I propose is to let programmer decide whether he will use Exception or not on endOfStream. And if he choose Exception, I underline that a defaultAction answering nil is not a panacea. But that defaultAction would still be an option if it solves your problem. Not sure my proposition does really solve the #next: problem you raised, indeed. The solution could be independant of endOfStream handling for this one. I support your request of creating a VW/Dolphin compatible #nextAvailable: and changing #next: to raise a NotEnoughElementAvailableError (maybe a subclass of EndOfStreamError). We would have a few package incompatibility, but, on ne fait pas d'omelette sans casser des oeufs... But I'm not convinced by the idea of duplicating the whole method protocol. Nor on duplicating the whole Stream class hierarchy, it's too big. That's were a classic delegation pattern can help (pluggable endOfStream). Of course, Trait composition is another option, and dynamic (on the fly) composition would be fun experimenting (as opposed to Static class definition). Keeping Traits as independant code units as possible is an interesting challenge (to explore the limits of such design). Nicolas 2009/6/9 Schwab,Wilhelm K <bschwab@anest.ufl.edu>:
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
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project