[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
|