[squeak-dev] [Discussion] Warning vs. Halt (or: "Why is a warning a notification?")
Thiede, Christoph
Christoph.Thiede at student.hpi.uni-potsdam.de
Mon Nov 4 13:41:55 UTC 2019
Hi all,
as you're talking about UI notifications, I would like to add my 2 cents:
I have always found the UIManagers' implementations of #inform:, #request:, #chooseFrom:, etc. a bit strange. They first signal a ProvideAnswerNotification, and then, if it was not handled and resumed, display a UI element to the user.
Why is this not rather implemented as a UserNotification, similar to the implementation of ParserNotifications? Pseudocode:
"Client code"
UIManager default inform: 'Carpe Squeak'.
UserNotification signal: 'Carpe Squeak'. "of course, we could also move this to Object >> #inform: again"
UIManager default chooseFrom: (1 to: 10).
UserNotification signalChoiceFrom: (1 to: 10).
UserNotification signalRequest: 'What's your name?' initialAnswer: Utilites authorName.
"Implementation"
UserNotification >> defaultAction
Project current uiManager inform: self messageText
UserNotification >> signalChoiceFrom: values "optional, for convenience"
^ UserChoiceNotification signalFrom: values
UserChoiceNotification >> signalFrom: values
^ self new
values: values;
signal
UserChoiceNotification >> defaultAction
^ Project current uiManager chooseFrom: self values
MorphicUIManager >> inform: aString
self askForProvidedAnswerTo: aString ifSupplied: [:answer |
^ answer].
^ UserDialogBoxMorph inform: aString
Advantages:
* Each notification is completely represented by a full-fledged first-class object - whereas a ProvideAnswerNotification maps the actual notification quite badly: it does not even store the values to choose from, an initial answer, etc...
* Not only, but particularly in tests: You could do amazing things such as
* self
should: [ modelUnderTest doSomeOperation ]
raise: UserChoiceNotification
withExceptionDo: [ :notification |
self
should: [ '*file*exists*' match: notification messageText ];
should: [ notification values includes: 'overwrite that file' ] ].
* Instead of the hardcoded resumption values for canceling (#cancel and true), you could just implement #cancel on UserNotification and say:
[ self chooseFrom: #(one two three) ] on: UserNotification do: #cancel
* (By the way, these hardcoded values currently lead to a strange behavior of the following snippet:
[ UIManager default chooseFrom: #(true false) ]
valueSuppressingMessages: #('*') "returns 1 instead of 0")
* Currently, we have massive duplication of calls to #askForProvidedAnswerTo:ifSupplied: in each UIManager. If we inversed the call chain as proposed, UIManagers could refocus on their task to display UI elements.
* Maybe this change would allow us to move all the convenience methods with default parameters from UIManager into the special UserNotification classes, to tidy up the things a bit :)
Disadvantages:
* Compatibility issues: (How) could we preserve the behavior of all current clients that directly call UIManager?
* Add yours here :-)
Best,
Christoph
________________________________
Von: Squeak-dev <squeak-dev-bounces at lists.squeakfoundation.org> im Auftrag von Jakob Reschke <forums.jakob at resfarm.de>
Gesendet: Samstag, 2. November 2019 17:36 Uhr
An: The general-purpose Squeak developers list
Betreff: Re: [squeak-dev] [Discussion] Warning vs. Halt (or: "Why is a warning a notification?")
Marcel Taeumel <marcel.taeumel at hpi.de<mailto:marcel.taeumel at hpi.de>> schrieb am Sa., 2. Nov. 2019, 13:54:
Hmmm..... Notifcations that claim to be resumable but require user input in #defaultAction feel kind of awkwardly designed...
Yes they are. After all they don't really have a default value that should be automatically determined. Or in other words they must be handled and if they are not they force you to handle them manually. In that regard they behave more like Errors, which are manually handled in the debugger. They are not errors from a functional perspective though.
In that sense, I can also resume any error with "nil" (or "false") if I want to....
...which is what you get when you press "proceed", right? But you are not allowed to send #resume or #resume: to them.
#resume with default value does not make much sense for those request exceptions either.
A more sensible pattern might be:
value := RequestNotification signal.
value ifNil: [self showUiRequest].
But you cannot enforce it anyway.
Also these requests are mostly UI situations which want to be unit-testable and therefore use these exceptions, aren't they? So they might not be amenable or relevant for catch-all exception handling for server purposes anyway.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20191104/1e5fa065/attachment.html>
More information about the Squeak-dev
mailing list
|