[squeak-dev] Smalltalk global instances

Levente Uzonyi leves at elte.hu
Sun Jan 9 16:21:04 UTC 2011


On Sun, 9 Jan 2011, Frank Shearar wrote:

> Hi,
>
> I ran into a pair of bugs by accident 
> (http://bugs.squeak.org/view.php?id=7595 and 
> http://bugs.squeak.org/view.php?id=7596) that are caused by the same problem.
>
> If you have a MessageNames that shows Undeclared, and you select Undeclared, 
> you get a pair of walkbacks because code that expects a class actually gets a 
> Dictionary. The problem stems from Smalltalk classNamed: #Undeclared 
> returning something that's not actually a class. (I suspect this kind of bug 
> will manifest for other non-class globals.)
>
> Now one workaround is possibly to turn code like this:
>
> selectedClassOrMetaClass
> 	"Answer the currently selected class (or metaclass)."
> 	messageListIndex > 0 ifTrue: [
> 		^ self setClassAndSelectorIn: [:c :s | ^c]].
> 	(selectorListIndex isNil not and: [selectorListIndex > 0]) ifTrue: 
> [^Smalltalk classNamed: (self selectorList at: selectorListIndex)].
> 		^ nil.
>
> into something like this:
>
> selectedClassOrMetaClass
> 	"Answer the currently selected class (or metaclass)."
> 	messageListIndex > 0 ifTrue: [
> 		^ self setClassAndSelectorIn: [:c :s | ^c]].
> 	(selectorListIndex isNil not and: [selectorListIndex > 0]) ifTrue:
> 		[ | cls |
> 		cls := Smalltalk classNamed: (self selectorList at: 
> selectorListIndex).
> 		^(cls isKindOf: Behavior) ifTrue: [cls]].
> 		^ nil.
>
> I dislike this. You'd have to check the result of #classNamed: for being a 
> class!
>
> I'd rather fix the underlying problem, and change 
> SystemDictionary>>classOrTraitNamed: so that the last clause said something 
> like
>
> 	baseClass := Smalltalk at: baseName asSymbol ifAbsent: [^ nil].
> 	meta
> 		ifTrue: [^ baseClass classSide]
> 		ifFalse: [^ (baseClass isKindOf: Behavior) ifTrue: 
> [baseClass]]
>
> That doesn't seem to smash up anything, but is the above _sane_?

It's an old idea to ensure that #classNamed: returns a class (or maybe a 
trait), but I'm not sure it won't break anything.
I think it would be better to write it like this:

 	^self at: baseName asSymbol ifPresent: [ :global |
 		global isBehavior ifTrue: [
 			meta
 				ifFalse: [ global ]
 				ifTrue: [ global classSide ] ] ]


Levente

>
> frank
>
>



More information about the Squeak-dev mailing list