It depends on your OrderedCollection implementation.

OrderedCollection has a variable size in memory. When instantiated, it has
for example 10 slots, and if you have more than 10 objects, it needs to
change its size to hold more slots.

The current implementation relies on an indirection to an array, when the
array overflows, the orderedCollection allocates a new bigger array and
copy the slots from the existing array. There are some heuristics on array
size to avoid having to grow the array too often.

If you want the shallowCopy to work, you have to use the old implementation
of OrderedCollection, which encodes in its field directly the values it
holds. In this case however when the collection overflows you create a new
orderedCollection so you need to use #become: to migrate references to the
old orderedCollection to the new one. This used to be a bad idea because
the become primitive was slow, but since we have Spur, it may be relevant
to look at it again. This old implementation is more memory efficient too.

2015-02-20 8:05 GMT+01:00 Marcus Denker <marcus.den...@inria.fr>:

>
> On 20 Feb 2015, at 06:23, S Krish <krishnamachari.sudha...@gmail.com>
> wrote:
>
>
> I presumed shallowCopy for literal arrays / OrderedCollection should have
> been a true copy. Perhaps need to understand this..
>
>
> OrderdCollection is not just one object, but it holds on to an Array that
> has it’s content. You copy the outside collection object, but share
> the Array.
>
> shallowCopy
>     "Answer a copy of the receiver which shares the receiver's instance
> variables. It should never be overridden. I'm invoked from the copy
> template method. Subclasses that need to specialize the copy should
> specialize the postCopy hook method."
>    ...
>     <primitive: 148>
>     class := self class.
>     class isVariable
>         ifTrue:
>             [...   newObject :=* class basicNew: index*. ....]
>         ifFalse: [newObject := *class basicNew*].
>     ..
>         whileTrue:
>             [newObject instVarAt: index put: (self instVarAt: index).
>            ...
>     ^ newObject
>
> On Wed, Feb 18, 2015 at 10:52 PM, Marcus Denker <marcus.den...@inria.fr>
> wrote:
>
>>
>> On 18 Feb 2015, at 18:13, Cameron Sanders via Pharo-users <
>> pharo-users@lists.pharo.org> wrote:
>>
>>
>> *Date: *18 Feb 2015 18:12:33 CET
>> *Subject: **i feel dumb / Pharo3 > OrderedCollection >> do:*
>> *From: *Cameron Sanders <camsand...@aol.com>
>> *To: *Any question about pharo is welcome <pharo-users@lists.pharo.org>
>>
>>
>> I must be making some silly error here that i cannot see clearly. Why
>> does the following leave anything in the list 'a'? Run it in a workspace.
>> With or without the shallowCopy, i am left with a list with half of the
>> elements in it. Always half.
>>
>> This version of Pharo3 (21.0) was downloaded last week. I am running on a
>> Mac.
>>
>> Thanks in advance. ... Maybe I just need more coffee.
>> -Cam
>>
>> | a  |
>> a := {  #a. #b. #c. #d. } asOrderedCollection.
>> a shallowCopy do: [ :item | (a includes: item) ifTrue: [ a remove: item
>> ]].
>> a size
>>
>>
>> shallowCopy is not enough… OrderedCollection is made up of an internal
>> array.
>>
>> #copy does the right thing, just copies the array:
>>
>> postCopy
>> array := array copy
>>
>> and for Array, copy is a shallowCopy.
>>
>> Marcus
>>
>>
>>
>>
>
>

Reply via email to