Structure.st
changeset 2341 d05835f10cb8
parent 2215 8ae61b93c7eb
child 2351 4371af1faf81
equal deleted inserted replaced
2340:0099dfc0e1a2 2341:d05835f10cb8
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 "{ Package: 'stx:libcomp' }"
    12 "{ Package: 'stx:libcomp' }"
    13 
    13 
    14 Object subclass:#Structure
    14 Object subclass:#Structure
    15 	instanceVariableNames:'superclass flags methodDictionary instSize i1 i2 i3 i4 i5 i6 i7
    15         instanceVariableNames:'superclass flags methodDictionary lookupFunction instSize i1 i2 i3 i4 i5 i6 i7
    16 		i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20 i21 i22 i23 i24
    16                 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20 i21 i22 i23 i24
    17 		i25 i26 i27 i28 i29 i30 i31 i32 i33 i34 i35 i36 i37 i38 i39 i40
    17                 i25 i26 i27 i28 i29 i30 i31 i32 i33 i34 i35 i36 i37 i38 i39 i40
    18 		i41 i42 i43 i44 i45 i46 i47 i48 i49 i50'
    18                 i41 i42 i43 i44 i45 i46 i47 i48 i49 i50'
    19 	classVariableNames:'OneInstance DummyClass ReadAccessMethods WriteAccessMethods
    19         classVariableNames:'OneInstance DummyClass ReadAccessMethods WriteAccessMethods
    20 		OtherMethods OtherSelectors'
    20                 OtherMethods OtherSelectors'
    21 	poolDictionaries:''
    21         poolDictionaries:''
    22 	category:'Programming-Support'
    22         category:'Programming-Support'
    23 !
    23 !
    24 
    24 
    25 !Structure class methodsFor:'documentation'!
    25 !Structure class methodsFor:'documentation'!
    26 
    26 
    27 copyright
    27 copyright
    60         retVal foo
    60         retVal foo
    61         retVal bar
    61         retVal bar
    62 
    62 
    63     Implementation note:
    63     Implementation note:
    64         this is a very tricky (but fully legal) implementation,
    64         this is a very tricky (but fully legal) implementation,
    65         creating an object which is its own class. 
    65         creating an object which is its own class.
    66         Therefore, no additional overhead by extra (class) objects is involved.
    66         Therefore, no additional overhead by extra (class) objects is involved.
    67         These are very lightweight objects.
    67         These are very lightweight objects.
    68 
    68 
    69         Another prove that smalltalk is a powerful & flexible programming language.
    69         Another prove that smalltalk is a powerful & flexible programming language.
    70         However, some smalltalk systems crash if your try this ;-)
    70         However, some smalltalk systems crash if your try this ;-)
    80 
    80 
    81     [author:]
    81     [author:]
    82         Claus Gittinger
    82         Claus Gittinger
    83 
    83 
    84     [see also:]
    84     [see also:]
    85         Array 
    85         Array
    86         Behavior
    86         Behavior
    87 "
    87 "
    88 !
    88 !
    89 
    89 
    90 examples
    90 examples
   120 
   120 
   121 !Structure class methodsFor:'initialization'!
   121 !Structure class methodsFor:'initialization'!
   122 
   122 
   123 initialize
   123 initialize
   124     OneInstance isNil ifTrue:[
   124     OneInstance isNil ifTrue:[
   125         Behavior instSize ~~ 4 ifTrue:[
   125         "/ check if the first few instvars correspond to Behavior's definition:
   126             self halt:'must change definition of this class'.
   126 
       
   127         (Behavior instSize + 1) == (self instanceVariableNames indexOf:#i1) ifFalse:[
       
   128             self halt:'you must change the definition of this class (instvars before i1 must match behavior''s)'.
   127         ].
   129         ].
   128 
   130 
   129         OneInstance := self basicNew.
   131         OneInstance := self basicNew.
   130 
   132 
   131         DummyClass := Behavior shallowCopy.
   133         DummyClass := Behavior shallowCopy.
   132         DummyClass flags:(Behavior flagBehavior bitOr:Behavior flagPointers).
   134         DummyClass flags:(Behavior flagBehavior bitOr:Behavior flagPointers).
   133         DummyClass setName:#DummyClass.
   135         DummyClass setName:#DummyClass.
   134 
   136 
   135         ReadAccessMethods := (1 to:50) 
   137         ReadAccessMethods := (1 to:50)
   136                                 collect:[:i | |m|
   138                                 collect:[:i | |m|
   137                                             m := self compiledMethodAt:('i', i printString) asSymbol.
   139                                             m := self compiledMethodAt:('i', i printString) asSymbol.
   138                                             (m notNil and:[m isLazyMethod]) ifTrue:[m makeRealMethod].
   140                                             (m notNil and:[m isLazyMethod]) ifTrue:[m makeRealMethod].
   139                                             m
   141                                             m
   140                                 ].
   142                                 ].
   141         WriteAccessMethods := (1 to:50) 
   143         WriteAccessMethods := (1 to:50)
   142                                 collect:[:i | |m|
   144                                 collect:[:i | |m|
   143                                             m := self compiledMethodAt:('i', i printString , ':') asSymbol.
   145                                             m := self compiledMethodAt:('i', i printString , ':') asSymbol.
   144                                             (m notNil and:[m isLazyMethod]) ifTrue:[m makeRealMethod].
   146                                             (m notNil and:[m isLazyMethod]) ifTrue:[m makeRealMethod].
   145                                             m
   147                                             m
   146                                 ].
   148                                 ].
   147 
   149 
   148         OtherMethods := OrderedCollection new.
   150         OtherMethods := OrderedCollection new.
   149         OtherMethods 
   151         OtherMethods
   150             add:(self compiledMethodAt:#doesNotUnderstand:);
   152             add:(self compiledMethodAt:#doesNotUnderstand:);
   151             add:(Object compiledMethodAt:#class);
   153             add:(Object compiledMethodAt:#class);
   152             add:(Object compiledMethodAt:#identityHash);
   154             add:(Object compiledMethodAt:#identityHash);
   153             add:(Object compiledMethodAt:#at:);
   155             add:(Object compiledMethodAt:#at:);
   154             add:(Object compiledMethodAt:#at:put:);
   156             add:(Object compiledMethodAt:#at:put:);
   164             add:(Object compiledMethodAt:#perform:);
   166             add:(Object compiledMethodAt:#perform:);
   165             add:(Object compiledMethodAt:#perform:with:);
   167             add:(Object compiledMethodAt:#perform:with:);
   166             add:(Object compiledMethodAt:#isBoolean).
   168             add:(Object compiledMethodAt:#isBoolean).
   167         OtherMethods := OtherMethods asArray.
   169         OtherMethods := OtherMethods asArray.
   168 
   170 
   169         OtherSelectors := #(#doesNotUnderstand: 
   171         OtherSelectors := #(#doesNotUnderstand:
   170                             #class #identityHash
   172                             #class #identityHash
   171                             #at: #at:put: #basicAt: #basicAt:put: 
   173                             #at: #at:put: #basicAt: #basicAt:put:
   172                             #printString #printOn: #basicPrintOn:
   174                             #printString #printOn: #basicPrintOn:
   173                             #addDependent: #removeDependent: #dependents #dependents:
   175                             #addDependent: #removeDependent: #dependents #dependents:
   174                             #perform: #perform:with:
   176                             #perform: #perform:with:
   175                             #isBoolean).
   177                             #isBoolean).
   176     ].
   178     ].
   210 
   212 
   211     sels := names collect:[:nm | nm asSymbol].
   213     sels := names collect:[:nm | nm asSymbol].
   212     sels := sels , (names collect:[:nm | (nm , ':') asSymbol]).
   214     sels := sels , (names collect:[:nm | (nm , ':') asSymbol]).
   213     sels := sels , OtherSelectors.
   215     sels := sels , OtherSelectors.
   214 
   216 
   215     mthds := ReadAccessMethods copyTo:nInsts. 
   217     mthds := ReadAccessMethods copyTo:nInsts.
   216     mthds := mthds , (WriteAccessMethods copyTo:nInsts).
   218     mthds := mthds , (WriteAccessMethods copyTo:nInsts).
   217     mthds := mthds , OtherMethods.
   219     mthds := mthds , OtherMethods.
   218 
   220 
   219     "/ create a prototype object as an array ...
   221     "/ create a prototype object as an array ...
   220     "/ the object will be its own class, and have the indexable flag bit set;
   222     "/ the object will be its own class, and have the indexable flag bit set;
   224 
   226 
   225     arr := Array new:(behviorsInstSize + nInsts).
   227     arr := Array new:(behviorsInstSize + nInsts).
   226     arr at:1 put:nil.                                                   "/ superclass
   228     arr at:1 put:nil.                                                   "/ superclass
   227     arr at:2 put:(Behavior flagBehavior bitOr:Behavior flagPointers).   "/ flags
   229     arr at:2 put:(Behavior flagBehavior bitOr:Behavior flagPointers).   "/ flags
   228     arr at:3 put:(MethodDictionary withKeys:sels andValues:mthds).      "/ selectors & methods
   230     arr at:3 put:(MethodDictionary withKeys:sels andValues:mthds).      "/ selectors & methods
   229     arr at:4 put:behviorsInstSize.                                      "/ instSize 
   231     arr at:4 put:behviorsInstSize.                                      "/ instSize
   230 
   232 
   231     "/ now, the big trick ...
   233     "/ now, the big trick ...
   232 
   234 
   233     arr changeClassTo:DummyClass.
   235     arr changeClassTo:DummyClass.
   234     arr changeClassTo:arr.
   236     arr changeClassTo:arr.
   237         values keysAndValuesDo:[:i :val |
   239         values keysAndValuesDo:[:i :val |
   238             arr at:i put:val
   240             arr at:i put:val
   239         ]
   241         ]
   240     ].
   242     ].
   241 
   243 
   242     ^ arr.  
   244     ^ arr.
   243 
   245 
   244     "
   246     "
   245      Structure newWith:#(foo bar) values:#('foo' 'bar')
   247      Structure newWith:#(foo bar) values:#('foo' 'bar')
   246     "
   248     "
   247 
   249 
   262 
   264 
   263 with:assoc1 with:assoc2
   265 with:assoc1 with:assoc2
   264     "return a new structure with two fields, named as defined by the arguments'
   266     "return a new structure with two fields, named as defined by the arguments'
   265      keys, and and initialized with the assocs' values."
   267      keys, and and initialized with the assocs' values."
   266 
   268 
   267      ^ self newWith:(Array with:assoc1 key with:assoc2 key) 
   269      ^ self newWith:(Array with:assoc1 key with:assoc2 key)
   268              values:(Array with:assoc1 value with:assoc2 value)
   270              values:(Array with:assoc1 value with:assoc2 value)
   269 
   271 
   270     "
   272     "
   271      Structure with:#foo->'foo' with:#bar->'bar'
   273      Structure with:#foo->'foo' with:#bar->'bar'
   272     "
   274     "
   274 
   276 
   275 with:assoc1 with:assoc2 with:assoc3
   277 with:assoc1 with:assoc2 with:assoc3
   276     "return a new structure with three fields, named as defined by the arguments'
   278     "return a new structure with three fields, named as defined by the arguments'
   277      keys, and and initialized with the assocs' values."
   279      keys, and and initialized with the assocs' values."
   278 
   280 
   279      ^ self newWith:(Array with:assoc1 key with:assoc2 key with:assoc3 key) 
   281      ^ self newWith:(Array with:assoc1 key with:assoc2 key with:assoc3 key)
   280              values:(Array with:assoc1 value with:assoc2 value with:assoc3 value)
   282              values:(Array with:assoc1 value with:assoc2 value with:assoc3 value)
   281 
   283 
   282     "
   284     "
   283      Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz'
   285      Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz'
   284     "
   286     "
   286 
   288 
   287 with:assoc1 with:assoc2 with:assoc3 with:assoc4
   289 with:assoc1 with:assoc2 with:assoc3 with:assoc4
   288     "return a new structure with four fields, named as defined by the arguments'
   290     "return a new structure with four fields, named as defined by the arguments'
   289      keys, and and initialized with the assocs' values."
   291      keys, and and initialized with the assocs' values."
   290 
   292 
   291      ^ self newWith:(Array with:assoc1 key with:assoc2 key 
   293      ^ self newWith:(Array with:assoc1 key with:assoc2 key
   292                            with:assoc3 key with:assoc4 key) 
   294                            with:assoc3 key with:assoc4 key)
   293              values:(Array with:assoc1 value with:assoc2 value 
   295              values:(Array with:assoc1 value with:assoc2 value
   294                            with:assoc3 value with:assoc4 value)
   296                            with:assoc3 value with:assoc4 value)
   295 
   297 
   296     "
   298     "
   297      Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello'
   299      Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello'
   298     "
   300     "
   300 
   302 
   301 with:assoc1 with:assoc2 with:assoc3 with:assoc4 with:assoc5
   303 with:assoc1 with:assoc2 with:assoc3 with:assoc4 with:assoc5
   302     "return a new structure with five fields, named as defined by the arguments'
   304     "return a new structure with five fields, named as defined by the arguments'
   303      keys, and and initialized with the assocs' values."
   305      keys, and and initialized with the assocs' values."
   304 
   306 
   305      ^ self newWith:(Array with:assoc1 key with:assoc2 key 
   307      ^ self newWith:(Array with:assoc1 key with:assoc2 key
   306                            with:assoc3 key with:assoc4 key      
   308                            with:assoc3 key with:assoc4 key
   307                            with:assoc5 key) 
   309                            with:assoc5 key)
   308              values:(Array with:assoc1 value with:assoc2 value 
   310              values:(Array with:assoc1 value with:assoc2 value
   309                            with:assoc3 value with:assoc4 value 
   311                            with:assoc3 value with:assoc4 value
   310                            with:assoc5 value)
   312                            with:assoc5 value)
   311 
   313 
   312     "
   314     "
   313      Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' with:#world->'world'
   315      Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' with:#world->'world'
   314     "
   316     "
   316 
   318 
   317 with:assoc1 with:assoc2 with:assoc3 with:assoc4 with:assoc5 with:assoc6
   319 with:assoc1 with:assoc2 with:assoc3 with:assoc4 with:assoc5 with:assoc6
   318     "return a new structure with five fields, named as defined by the arguments'
   320     "return a new structure with five fields, named as defined by the arguments'
   319      keys, and and initialized with the assocs' values."
   321      keys, and and initialized with the assocs' values."
   320 
   322 
   321      ^ self newWith:(Array with:assoc1 key with:assoc2 key 
   323      ^ self newWith:(Array with:assoc1 key with:assoc2 key
   322                            with:assoc3 key with:assoc4 key      
   324                            with:assoc3 key with:assoc4 key
   323                            with:assoc5 key with:assoc6 key) 
   325                            with:assoc5 key with:assoc6 key)
   324              values:(Array with:assoc1 value with:assoc2 value 
   326              values:(Array with:assoc1 value with:assoc2 value
   325                            with:assoc3 value with:assoc4 value 
   327                            with:assoc3 value with:assoc4 value
   326                            with:assoc5 value with:assoc6 value)
   328                            with:assoc5 value with:assoc6 value)
   327 
   329 
   328     "
   330     "
   329      Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' with:#world->'world'
   331      Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' with:#world->'world'
   330     "
   332     "
   332 
   334 
   333 with:assoc1 with:assoc2 with:assoc3 with:assoc4 with:assoc5 with:assoc6 with:assoc7
   335 with:assoc1 with:assoc2 with:assoc3 with:assoc4 with:assoc5 with:assoc6 with:assoc7
   334     "return a new structure with five fields, named as defined by the arguments'
   336     "return a new structure with five fields, named as defined by the arguments'
   335      keys, and and initialized with the assocs' values."
   337      keys, and and initialized with the assocs' values."
   336 
   338 
   337      ^ self newWith:(Array with:assoc1 key with:assoc2 key 
   339      ^ self newWith:(Array with:assoc1 key with:assoc2 key
   338                            with:assoc3 key with:assoc4 key      
   340                            with:assoc3 key with:assoc4 key
   339                            with:assoc5 key with:assoc6 key
   341                            with:assoc5 key with:assoc6 key
   340                            with:assoc7 key) 
   342                            with:assoc7 key)
   341              values:(Array with:assoc1 value with:assoc2 value 
   343              values:(Array with:assoc1 value with:assoc2 value
   342                            with:assoc3 value with:assoc4 value 
   344                            with:assoc3 value with:assoc4 value
   343                            with:assoc5 value with:assoc6 value
   345                            with:assoc5 value with:assoc6 value
   344                            with:assoc7 value)
   346                            with:assoc7 value)
   345 
   347 
   346     "
   348     "
   347      Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' with:#world->'world'
   349      Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' with:#world->'world'
  1410                         idx := idx + 1.
  1412                         idx := idx + 1.
  1411                     ].
  1413                     ].
  1412                 ]
  1414                 ]
  1413             ]
  1415             ]
  1414         ].
  1416         ].
  1415         
  1417 
  1416          ^ names
  1418          ^ names
  1417     ].
  1419     ].
  1418 
  1420 
  1419     (sel == #instSize) ifTrue:[
  1421     (sel == #instSize) ifTrue:[
  1420          ^ instSize
  1422          ^ instSize
  1431 ! !
  1433 ! !
  1432 
  1434 
  1433 !Structure class methodsFor:'documentation'!
  1435 !Structure class methodsFor:'documentation'!
  1434 
  1436 
  1435 version
  1437 version
  1436     ^ '$Header: /cvs/stx/stx/libcomp/Structure.st,v 1.23 2009-10-08 14:01:57 mb Exp $'
  1438     ^ '$Header: /cvs/stx/stx/libcomp/Structure.st,v 1.24 2010-04-07 14:53:33 cg Exp $'
  1437 !
  1439 !
  1438 
  1440 
  1439 version_CVS
  1441 version_CVS
  1440     ^ '$Header: /cvs/stx/stx/libcomp/Structure.st,v 1.23 2009-10-08 14:01:57 mb Exp $'
  1442     ^ '$Header: /cvs/stx/stx/libcomp/Structure.st,v 1.24 2010-04-07 14:53:33 cg Exp $'
  1441 ! !
  1443 ! !
  1442 
  1444 
  1443 Structure initialize!
  1445 Structure initialize!