Squeak has a long tradition of silent failures of all types (in the image and
the vm), and IMNSHO, it is a **really** bad idea with terrible consequences and
needs to be fixed. Default actions that return nil merely push problems down
stream to a point where there is no context to figure out what went wrong. I
think much of this goes back to the late 70's and early 80's, before structured
exception handling, and has never been modernized. Dolphin, which started life
in the mid 90's, is built from the ground up to do these things correctly.
Once one learns that the exceptions are indeed helping to make things work
reliably, it is hard to imagine making something robust without them.
Exceptions can be expensive, both to set up handlers, and even more so when
exceptions are thrown. You have identified the answer, which is to provide
#readFrom:ifFail: (or #readFrom:onError: - whatever you want to call it) that
evaluates a block when things go wrong, which allows one to bypass the
overhead, much like #at:ifAbsent:; if error and remedy are near by, it is easy
to do and skips the overhead. For the lazy<g>, or simply for frameworks that
can/should use exceptions to handle exceptional conditions (big separation
between the problem and anything that knows how to cope with it), #readFrom:
(without the block) does the robust/correct thing, and raises an exception. As
you no doubt know, it can (often should) be written in terms of
#readFrom:ifFail: with the block raising the exception.
Things will break for a while, but I hesitate to think how much stuff is just
plain broken and we never notice it because things answer nil and/or ignore
error conditions. The industry tried to formalize such
head-in-the-sand-hope-it-goes-away design under the fancy name "defensive
programming." It remains a useful approach when used sparingly to keep
critical systems running, but it generally failed under its own lack of merit.
It was popularized as a way to cope with the dreaded UAEs of 16 bit Windows,
which was in turn due to the lack of exception handling and ensured execution
in the GUI, which lead to incomplete cleanup, memory leaks, and all kinds of
crashes.
YES. PLEASE DO THIS. **GREAT** IDEA. You might take a look at
http://www.squeaksource.com/PharoInbox/DolphinCompatibility-Streams-BillSchwab.1.mcz
for what I consider to be very much related changes to stream I/O. Since it
quickly became obvious to me that #next and #next: were not going to change any
time soon, I simply stopped using them myself; instead I write code using
#nextOne, #nextMany:, and #nextAvailable:. You will also find methods such as
#nextDWORD to help with binary file formats, device interfacing, etc .
It is a work in progress, but the idea is to have read streams bark when they
run out of data, unless (#nextAvailable:) specifically authorized to truncate.
I also have some text converters modeled after Dolphin's framework. I don't
think I have released those yet, but plan to do so eventually. Because of the
problem you have identified, I have added some tests (and throw exceptions when
they fail) for whether the stream is or is not at the end or read an expected
number of types, etc.
Thanks for working on this!
Bill
________________________________________
From: [email protected]
[[email protected]] On Behalf Of Guillermo Polito
[[email protected]]
Sent: Tuesday, August 24, 2010 4:33 PM
To: [email protected]
Subject: [Pharo-project] String to Number conversion
http://code.google.com/p/pharo/issues/detail?id=2857
Which will be the impact in the system and other tools to throw an error when
the conversion cannot take place?
I think an error must be thrown, but should it be in Pharo 1.2 or in next
version?
On Tue, Aug 24, 2010 at 11:45 AM, Nicolas Cellier
<[email protected]<mailto:[email protected]>>
wrote:
In squeak, (Integer readFromString: 'foo') ->Error
Use:
- Integer readFrom: 'foo' ifFail: [0], tp get backward compatibility,
- (Integer readFrom: 'foo' ifFail: []), to get nil
Though it is possible, I dislike anwsering nil, because it would mean
a bunch of #readFrom: send should be protected by #ifNil: Blocks...
1) That's nonsense, readFrom:ifFail: already does the work.
2) you cripple the code with Error conditions and end up with
unreadable C-looking like code
(3 lines of Error condition crap for 1 line of underlying algorithm
at every function call)
3) Exception handling can avoid long chains of ifFail: / ifNil: tests
But that conversation already took place many times...
I'd like the readFrom:ifFail: form to be generalized to other objects,
with default behaviour raising an Error. What do you think ?
Nicolas
2010/8/24 Johan Brichau <[email protected]<mailto:[email protected]>>:
>
> On 24 Aug 2010, at 15:19, Stéphane Ducasse wrote:
>
>> I thought that readFromString: was raising an error and that guessNumber*
>> was returning zero
>
> I thought that too. I even have application code that shows that this used to
> return nil in some version of Pharo...
> But:
>
> 'foo' asInteger = nil
> Integer readFromString: 'foo' = 0
> 'foo' asNumber -> Error
>
> aargh :-(
>
> disclaimer: currently testing this in pharo1.1
>
> Johan
> _______________________________________________
> Pharo-project mailing list
> [email protected]<mailto:[email protected]>
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
_______________________________________________
Pharo-project mailing list
[email protected]<mailto:[email protected]>
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________
Pharo-project mailing list
[email protected]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project