Disabling: Unknown selector, please confirm, correct, orcancel
Dan.Ingalls at disney.com
Mon Dec 11 15:28:14 UTC 2000
>Is it possible to disable the, "Unknown selector, please confirm,
>correct or cancel" menu for a specific class? Would it be an
>ugly hack? I have an unusual class that I want to 'talk to',
>by sending it any ol' message, and have it determine what to do
>by intercepting the DNU.
>The DNU-intercept part works, of course, and the "Unknown selector"
>menu seems to pop up only once--or rather, stops popping up after
>I've confirmed the message. Still, unknown selectors will be the
>norm here, rather than the exception, so I'd love to disable the
>menu altogether, for this class. . . . Is it a remote possibility
>this can be done, and not be totally gross? (I'm a Squeak/Smalltalk
The "unknown selector" message occurs when the selector that is being compiled has never been made into a Symbol before, and this can be determined with the message
Symbol hasInterned: aString ifTrue: [:sym | ...].
So if you know the possible message names you wish to support, then simply stache them in some enduring array (for a normal class, defining methods with these selectors suffices), and you will never see this message.
If this is not possible -- ie you wish to handle message names that cannot be anticipated (so as to take them apart or support, eg, optional message parts and the like), then you must, as you opined, disable this feature.
If you examine the senders of the above message, then you will see one in
Parser>>messagePart: level repeat: repeat
This is the part of the Squeak compiler that compiles message names, and invokes the "unknown selector" mechanism as follows...
The current code (which is under construction for Environments) is
(Symbol hasInterned: selector contents ifTrue: [ :sym | selector _ sym])
ifFalse: [ selector _ self correctSelector: selector contents
exprInterval: (start to: self endOfLastToken)
ifAbort: [ ^ self fail ] ].
At this point in the code (or perhaps better in correctSelector...) you can access the class in which this method is being compiled by the expression "encoder classEncoding". You will see that Parser>>correctSelector: ... begins with the line...
self interactive ifFalse: [^ proposedKeyword asSymbol].
You could add a line such as...
(encoder classEncoding allowsSelector: proposedSelector)
ifTrue: [^ proposedKeyword asSymbol]. "allow any selector"
which would admit any selector *to be compiled in* a class that answers true to "allowsSelector: proposedSelector" here (you will need a default that reutrns false in Behavior).
This, of course is different from allowing any selector *to be sent to* MyClass. If you wish to do this, then you can simply override the entire mechanism with, eg,
true ifTrue: [^ proposedKeyword asSymbol]. "Allow any selector for now"
and sort things out in DNU.
Or, if your valid selectors can somehow be recognized, you could use, eg,
(MyClass canRecognize: proposedSelector) ifTrue: [^ proposedKeyword asSymbol]
Hope this helps.
More information about the Squeak-dev