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