Here's a useful little addition for anyone who, like me, tends to type
faster than they should. Some typing errors, misspelt variable names for example, are caught by the compiler. However, mistakes in the spelling of selector names get past the compiler and result in DNU walkbacks. After making the following changes a check is made, when a method is saved, to ensure that all the selectors referenced by the method actually exist. If not a warning is flagged on the ClassBrowser/MethodBrowser status bar giving the name of the missing method(s). Two important points - It may be that you have just not yet got round to defining the missing method and because of this the patch works as an advisor only. It does not affect the compiled method or the operation of the browser and doesn't make you acknowledge the warning. - It only checks that a method is defined _somewhere in the image for each selector. It makes no attempt to ensure that each selector is being used on a receiver that can understand it. It is important that you add the first two methods below _before_ modifying the third ADD MethodBrowser>>checkUndefined | undefined behaviors | behaviors := Class allBehaviors. "cache for performance" undefined := self method messages reject: [:eachMessage | behaviors anySatisfy: [:eachClass | eachClass includesSelector: eachMessage]]. undefined isEmpty ifTrue: [^self]. sourcePresenter showUndefined: undefined asSortedCollection ADD SmalltalkWorkspace>>showUndefined: aCollection (self errorModel notNil and: [self errorModel value isNil]) ifTrue: [ | stream | stream := String writeStream. stream nextPutAll: ' undefined selector'; nextPutAll: (aCollection size > 1 ifTrue: ['s:'] ifFalse: [':']); space. aCollection do: [:each | stream print: each; space]. self errorModel value: (Warning new messageText: stream contents). Sound errorBeep] MODIFY the following method by adding the following line before the return statement at the end of the method. The last two lines of code (ignoring the comment) should read as below MethodBrowser>>saveMethodInClass: class categories: categories ..... newMethod notNil ifTrue: [self checkUndefined]. ^newMethod. If you now add a method fred self bert you should get a warning that #bert is undefined but the compilation, and the addition of the method to the class, should still work as normal. Ian |
Ian
"Ian Bartholomew" <[hidden email]> wrote in message news:92vij7$m4u$[hidden email]... > Here's a useful little addition for anyone who, like me, tends to type > faster than they should. Some typing errors, misspelt variable names for > example, are caught by the compiler. However, mistakes in the spelling of > selector names get past the compiler and result in DNU walkbacks. > ... Another great idea. One small suggestion for a minor improvement. If you use 'Smalltalk allBehaviors' rather than 'Class allBehaviors' it will run a bit faster because the sys dictionary caches the current set of classes. Regards Blair |
In reply to this post by Ian Bartholomew
Excellent! Or how about this - no warning message, but instead the offending
selectors are highlighted in red: --- Modifiy CompiledMethod>>getColoredSource getColoredSource: aString "Private - Answer an RTF format source string from the source, aString, for the receiver." | coloredSource richText behaviors undefined | coloredSource := self compilerClass syntaxColorOfMethod: aString in: self methodClass. richText := coloredSource rtf. behaviors := Class allBehaviors. "cache for performance" undefined := self messages reject: [:eachMessage | behaviors anySatisfy: [:eachClass | eachClass includesSelector: eachMessage]]. undefined do: [ :eachSelector || stem | stem := eachSelector copyFrom: 1 to: (eachSelector indexOf: $: ifAbsent: [eachSelector size]). richText := richText copyReplaceAll: (' ', stem) with: (' {\cf3 ', stem, '}')]. coloredSource rtf: richText. ^coloredSource --- The colour highlighting is not completely foolproof - it (intentionally) only marks the first part of a multi-argument selector, and can incorrectly highlight parts of correct selectors. But for a dumb string-based method it's not too bad. John Aspinall Ian Bartholomew <[hidden email]> wrote in message news:92vij7$m4u$[hidden email]... > Here's a useful little addition for anyone who, like me, tends to type > faster than they should. Some typing errors, misspelt variable names for > example, are caught by the compiler. However, mistakes in the spelling of > selector names get past the compiler and result in DNU walkbacks. > > After making the following changes a check is made, when a method is saved, > to ensure that all the selectors referenced by the method actually exist. If > not a warning is flagged on the ClassBrowser/MethodBrowser status bar giving > the name of the missing method(s). > > Two important points > - It may be that you have just not yet got round to defining the missing > method and because of this the patch works as an advisor only. It does not > affect the compiled method or the operation of the browser and doesn't make > you acknowledge the warning. > - It only checks that a method is defined _somewhere in the image for each > selector. It makes no attempt to ensure that each selector is being used on > a receiver that can understand it. > > It is important that you add the first two methods below _before_ modifying > the third > > ADD > MethodBrowser>>checkUndefined > | undefined behaviors | > behaviors := Class allBehaviors. "cache for performance" > undefined := self method messages reject: [:eachMessage | > behaviors anySatisfy: [:eachClass | eachClass includesSelector: > eachMessage]]. > undefined isEmpty ifTrue: [^self]. > sourcePresenter showUndefined: undefined asSortedCollection > > ADD > SmalltalkWorkspace>>showUndefined: aCollection > (self errorModel notNil and: [self errorModel value isNil]) > ifTrue: [ | stream | > stream := String writeStream. > stream > nextPutAll: ' undefined selector'; > nextPutAll: (aCollection size > 1 ifTrue: ['s:'] ifFalse: [':']); > space. > aCollection do: [:each | stream print: each; space]. > self errorModel value: (Warning new messageText: stream contents). > Sound errorBeep] > > MODIFY the following method by adding the following line before the return > statement at the end of the method. The last two lines of code (ignoring > comment) should read as below > > MethodBrowser>>saveMethodInClass: class categories: categories > ..... > newMethod notNil ifTrue: [self checkUndefined]. > ^newMethod. > > If you now add a method > > fred > self bert > > you should get a warning that #bert is undefined but the compilation, and > the addition of the method to the class, should still work as normal. > > Ian > > > > > > > > > > > > > |
we (jwars) use the va assist pro product for visual age smalltalk by eric
clayberg that does exactly this and it is quite nice. right up there with color syntax highlighting and (dare I say) formatting. good job, ian. the va product also has a means of looking up all methods with mis-spellings. "John Aspinall" <[hidden email]> wrote in message news:92vttf$89n4e$[hidden email]... > Excellent! Or how about this - no warning message, but instead the offending > selectors are highlighted in red: > > --- > > Modifiy CompiledMethod>>getColoredSource > > getColoredSource: aString > "Private - Answer an RTF format source string from the source, aString, > for the receiver." > > | coloredSource richText behaviors undefined | > > coloredSource := self compilerClass syntaxColorOfMethod: aString in: self > methodClass. > richText := coloredSource rtf. > > behaviors := Class allBehaviors. "cache for performance" > undefined := self messages reject: > [:eachMessage | behaviors anySatisfy: [:eachClass | eachClass > includesSelector: eachMessage]]. > > undefined do: > [ :eachSelector || stem | > stem := eachSelector copyFrom: 1 to: (eachSelector indexOf: $: ifAbsent: > [eachSelector size]). > richText := richText copyReplaceAll: (' ', stem) with: (' {\cf3 ', stem, > '}')]. > > coloredSource rtf: richText. > > ^coloredSource > > --- > > The colour highlighting is not completely foolproof - it (intentionally) > only marks the first part of a multi-argument selector, and can > highlight parts of correct selectors. But for a dumb string-based method > it's not too bad. > > John Aspinall > > > > Ian Bartholomew <[hidden email]> wrote in message > news:92vij7$m4u$[hidden email]... > > Here's a useful little addition for anyone who, like me, tends to type > > faster than they should. Some typing errors, misspelt variable names for > > example, are caught by the compiler. However, mistakes in the spelling > > selector names get past the compiler and result in DNU walkbacks. > > > > After making the following changes a check is made, when a method is > saved, > > to ensure that all the selectors referenced by the method actually exist. > If > > not a warning is flagged on the ClassBrowser/MethodBrowser status bar > giving > > the name of the missing method(s). > > > > Two important points > > - It may be that you have just not yet got round to defining the missing > > method and because of this the patch works as an advisor only. It does not > > affect the compiled method or the operation of the browser and doesn't > make > > you acknowledge the warning. > > - It only checks that a method is defined _somewhere in the image for each > > selector. It makes no attempt to ensure that each selector is being used > on > > a receiver that can understand it. > > > > It is important that you add the first two methods below _before_ > modifying > > the third > > > > ADD > > MethodBrowser>>checkUndefined > > | undefined behaviors | > > behaviors := Class allBehaviors. "cache for performance" > > undefined := self method messages reject: [:eachMessage | > > behaviors anySatisfy: [:eachClass | eachClass includesSelector: > > eachMessage]]. > > undefined isEmpty ifTrue: [^self]. > > sourcePresenter showUndefined: undefined asSortedCollection > > > > ADD > > SmalltalkWorkspace>>showUndefined: aCollection > > (self errorModel notNil and: [self errorModel value isNil]) > > ifTrue: [ | stream | > > stream := String writeStream. > > stream > > nextPutAll: ' undefined selector'; > > nextPutAll: (aCollection size > 1 ifTrue: ['s:'] ifFalse: [':']); > > space. > > aCollection do: [:each | stream print: each; space]. > > self errorModel value: (Warning new messageText: stream contents). > > Sound errorBeep] > > > > MODIFY the following method by adding the following line before the > > statement at the end of the method. The last two lines of code (ignoring > the > > comment) should read as below > > > > MethodBrowser>>saveMethodInClass: class categories: categories > > ..... > > newMethod notNil ifTrue: [self checkUndefined]. > > ^newMethod. > > > > If you now add a method > > > > fred > > self bert > > > > you should get a warning that #bert is undefined but the compilation, > > the addition of the method to the class, should still work as normal. > > > > Ian > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
Donald,
> good job, ian. the va product also has a means of looking up > all methods with mis-spellings. I posted something like that a few months ago. It was a little browser that had two options, one showed a list of all selectors that were used but not implemented (and the method(s) that referenced each one) and the other showed all the methods that were implemented but not used. It wasn't as useful as I though it might be as there were too many things that legitimately fell into one of the two categories but were not actually errors. References to dynamically created methods is structure classes for example. Dolphin4 has made some changes in this area so I don't know if the app still works or can be improved - I can check if anyone is interested. Ian |
In reply to this post by John Aspinall-2
John,
> Excellent! Or how about this - no warning message, but instead the offending > selectors are highlighted in red: Neat, I hadn't thought of doing it that way. I'm not completely convinced about the advisability of modifying the coloured source like that though - there might well be occasions where I want the source but wouldn't want anything highlighted. Something to bear in mind anyway - thanks Ian |
In reply to this post by Ian Bartholomew
In article <92vij7$m4u$[hidden email]>,
"Ian Bartholomew" <[hidden email]> wrote: > Here's a useful little addition for anyone who, like me, tends to type > faster than they should. Some typing errors, misspelt variable names for > example, are caught by the compiler. However, mistakes in the spelling of > selector names get past the compiler and result in DNU walkbacks. > > After making the following changes a check is made, when a method is saved, > to ensure that all the selectors referenced by the method actually exist. If > not a warning is flagged on the ClassBrowser/MethodBrowser status bar giving > the name of the missing method(s). Squeak actually does something similar to this, except that if you have a misspelled selector, it warns you and brings up a list of similarly spelled selectors in the image for you to choose from. If you pick a different one, it replaces the selector(s) in your method and goes ahead and compiles it. This is a pretty cool feature, although in a way it's nice that your status bar warning does not interrupt you if you're just compiling a method which sends a not-yet-implemented message. - Doug Way (at riskmetrics dot com) Sent via Deja.com http://www.deja.com/ |
On Wed, 03 Jan 2001 23:16:17 GMT, Doug Way <[hidden email]> wrote:
>In article <92vij7$m4u$[hidden email]>, > "Ian Bartholomew" <[hidden email]> wrote: >> Here's a useful little addition for anyone who, like me, tends to type >> faster than they should. Some typing errors, misspelt variable names >for >> example, are caught by the compiler. However, mistakes in the spelling >of >> selector names get past the compiler and result in DNU walkbacks. >> >> After making the following changes a check is made, when a method is >saved, >> to ensure that all the selectors referenced by the method actually >exist. If >> not a warning is flagged on the ClassBrowser/MethodBrowser status bar >giving >> the name of the missing method(s). > >Squeak actually does something similar to this, except that if you have >a misspelled selector, it warns you and brings up a list of similarly >spelled selectors in the image for you to choose from. If you pick a >different one, it replaces the selector(s) in your method and goes ahead >and compiles it. > >This is a pretty cool feature, although in a way it's nice that your >status bar warning does not interrupt you if you're just compiling a >method which sends a not-yet-implemented message. Actually I really like this with Squeak. It can be used for intellisense or code completion. I wonder if they use the soundex algorithm. The only downside to this is that you must make a selection or fix it in case your method is not implemented. Maybe the solution in this case would be to have the option in a dialog box of defining an empty method and give it the class name or self. I think between this and Ian's code, Dolphin could legally claim it has code completion capabilities! Costas P.S. As I am still not up to speed with programming the tools, I apologize for not being able to implement code for this. |
In reply to this post by Ian Bartholomew
Slight update to the previous posting for anyone using the undefined method
check. When editing using the MethodBrowser it is possible for the method to disappear before the undefined check is reached (after renaming a class for example). The following modified method prevents the walkback in those situations and also includes Blair's previous suggestion. MethodBrowser>>checkUndefined | undefined behaviors | self method isNil ifTrue: [^self]. behaviors := Smalltalk allBehaviors. "cache for performance" undefined := self method messages reject: [:eachMessage | behaviors anySatisfy: [:eachClass | eachClass includesSelector: eachMessage]]. undefined isEmpty ifTrue: [^self]. sourcePresenter showUndefined: undefined asSortedCollection Ian |
Free forum by Nabble | Edit this page |