[squeak-dev] Smalltalk global instances

Frank Shearar frank.shearar at angband.za.org
Sun Jan 9 17:46:52 UTC 2011


On 2011/01/09 16:21, Levente Uzonyi wrote:
> 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 ] ] ]

I'll prepare an MCZ with tests, in the meantime, and try bang on the change.

It looks like System currently has two heads in trunk - System-bp.408 
and System-dtl.408. With a freshly updated trunk image, it thus looks 
like there are local changes to the image before I've done anything.

frank



More information about the Squeak-dev mailing list