MaClassDefinition in question

Chris Muller asqueaker at gmail.com
Sun Jul 29 19:28:01 UTC 2007


Thanks for the clarification Hilaire, you have indeed uncovered a bug,
and your fix is exactly what is needed.

In addition to your "index>0" guard, in
MaReadStrategy>>#forVariableNamed:onAny:readToDepth:, please also
remove this check:

	(aClass allInstVarNames includes: aString) ifFalse:
		[ MagmaUserError signal: aString , ' is not an attribute of ' , aClass name ].

This check does not account for the possibility that old versions of
classes might define that variable but the not any longer in the newer
versions.

Thanks for reporting this just in time to make it into release 40.

BTW, I was able to reproduce the problem easily with the script below.
 It wasn't too hard once I understood what you were trying to tell
me..

Regards,
  Chris

|session path inst1 rs2|
(Smalltalk includesKey: #TestClass) ifTrue: [ (Smalltalk at:
#TestClass) removeFromSystem ].
path := 'c:\temp\testReadStrategy1'.
MagmaRepositoryController delete: path.
MaObject subclass: #TestClass
	instanceVariableNames: 'oldVar commonVar'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Testing'.
inst1 := (Smalltalk at: #TestClass) new
	instVarNamed: 'oldVar' put: 'hello' ;
	instVarNamed: 'commonVar' put: Object new ;
	yourself.
MagmaRepositoryController create: path root: inst1.
session := MagmaSession openLocal: path.  session inspect.
session connectAs: 'test'.
"Get rid of the root".  Smalltalk garbageCollect.
"Now redefine TestClass, remove oldVar, add newVar."
MaObject subclass: #TestClass
	instanceVariableNames: 'commonVar newVar'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Testing'.
rs2 := (MaReadStrategy minimumDepth: 0)
	forVariableNamed: 'newVar' onAny: (Smalltalk at: #TestClass) readToDepth: 1 ;
	forVariableNamed: 'oldVar' onAny: (Smalltalk at: #TestClass) readToDepth: 1 ;
	forVariableNamed: 'commonVar' onAny: (Smalltalk at: #TestClass)
readToDepth: 1 ;
	yourself.
session readStrategy: rs2.
(Smalltalk at: #TestClass) allInstVarNames do:
	[ :each |
	self assert: (session root instVarNamed: each) maIsMutatingProxy not ].



On 7/26/07, Hilaire Fernandes <hilaire at ofset.org> wrote:
> Le Tue, 24 Jul 2007 22:53:58 -0400, Chris Muller a écrit:
>
> > Hi Hilaire, sorry for the delayed response; I have just returned from a holiday.
> >
> > Instances of MaClassDefinition are kept for each version of each class
> > that was ever committed to the repository.
> >
> > When a ReadStrategy is specified, it should work fine for the old and
> > new versions of the classes.  See
> > MaReadStrategy>>#convertSpecificationsToIdsUsing: to see that it does
> > indeed create depth-specifications for every known version of the
> > class.  The variable that does not exist in the old version will
> > simply
>
> Yes? From my analysis it seems the code is missing for this kind of
> situation. See bellow.
>
>
> >
> > There is no need to "remove" the instance of your domain as it evolves
> > with your class model; the new variables will have nil just like
> > Smalltalk until you populate them and commit.
> >
> > Can you try again to explain the exact problem you are having?
> > Perhaps a script that reproduces it would improve our mutual clarity?
>
> It is not easy to track the problem (or even reproduce it in another
> context), but it occures as you told from there in
> convertSpecificationsToIdsUsing: exactly at (self instVarMapFor: eachDef)
> in:
>
> [ depths
>         at: { eachDefinition id.  eachDefinition version } ifAbsentPut:
>                 [ self beNew.
>                 (self instVarMapFor: eachDef) ] ] ] ] ]
>
>
> My class has 4 definitions, and pb comes with id:156, version:1., no prior
> strategy is present for this version. So from then, throught: self
> instVarMapFor: eachDef, Magma tries to install a readstrategy for a
> variable #exerciceAtStart not present in version 1 of the class
> definition (variable eachDef).
>
> In instVarMapFor:
>
> [ answer := self depthArrayOfSize: aMaClassDefinition namedInstSize.
>         specifiedDepths keysAndValuesDo:
>                 [ : eachInstVarName : eachDepth |
>                         answer
>                                 at: (aMaClassDefinition allInstVarNames indexOf: eachInstVarName)
>                                 put: eachDepth ] ] ]
>
> Here
> answer=#(0 0 0 0 0 0 0 0 0) (looks ok)
>
> specifiedDepths=Dictionary(#exercice->999 #exerciceAtStart->999 ) (looks
> ok)
>
> but with eachInstVarName=#exerciceAtStart
>
> (aMaClassDefinition allInstVarNames indexOf: eachInstVarName) is 0
>
> Indeed aMaClassDefinition is definition version 1 where exerciceAtStart
> instance variable is not present.
>
> Obviously there is a situation there.
>
> The change to the method below prevents the error, but I really don't
> know if this is the way to do it:
>
> [:eachInstVarName :eachDepth |
>         index :=  (aMaClassDefinition allInstVarNames indexOf: eachInstVarName).
>         index > 0 ifTrue:
>                 [answer
>                         at: index
>                         put: eachDepth] ]
>
>
> Hilaire
>
> _______________________________________________
> Magma mailing list
> Magma at lists.squeakfoundation.org
> http://lists.squeakfoundation.org/mailman/listinfo/magma
>


More information about the Magma mailing list