[squeak-dev] Smalltalk global instances

Frank Shearar frank.shearar at angband.za.org
Sun Jan 9 14:36:37 UTC 2011


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_?

frank



More information about the Squeak-dev mailing list