LookupTable>>shallowCopy a bit too shallow?!

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

LookupTable>>shallowCopy a bit too shallow?!

Bernhard Kohlhaas-6
Hello all,

After an hour of debuggin I have now traced a problem of mine down to an
"unexpected behavior" of LookupTable>>shallowCopy. I would have expected
it to copy all necessary internal data and maintenance structures, but
keep a reference to the same keys and values.

However that doesn't happen, since the instance variable 'values' isn't
copied, so removing keys from the copy of the LookupTable also affects
the original, i.e.
   t1 := LookupTable new
    at: 1 put: 'one';
                yourself.
   t2 := t1 shallowCopy.
   t1 removeKey: 1.
   t2

evaluates to: a LookupTable(1 -> nil).

I noticed that LookupTable>>copy invokes a #postCopy and using #copy
instead of #shallowCopy does the trick.

I do have a few questions regarding this and hope that someone can help me:

- Is this the way it's meant to be, that sending #shallowCopy doesn't
guarantee a properly functioning copy?

- If so should I avoid #shallowCopy for collection classes and just use
#copy to copy the container, but not the elements or should I always
send a #postCopy after a #shallowCopy?

- If the latter, WHEN should I send  #postCopy? I've noticed that there
are a lot of #shallowCopy sends, where a #postCopy isn't sent, i.e.
MessageSend>>forwardTo:withArguments: . I assume it isn't necessary due
to the implementation of the receiver, but I wouldn't want to have to
know too many implementation details about the receiver to decide when
to use it.

All in all I would have expected an implementation of #shallowCopy in
LookupTable (or one of its superclasses) that super-sends and afterwards
sends #postCopy (and then the #copy method simply sending #shallowCopy),
so I wouldn't have to worry about this at all.

Looking foward to any comments on the matter,

Bernhard


Reply | Threaded
Open this post in threaded view
|

Re: LookupTable>>shallowCopy a bit too shallow?!

Sergey Philippov
Bernhard Kohlhaas wrote:
> Hello all,
>
> After an hour of debuggin I have now traced a problem of mine down to an
> "unexpected behavior" of LookupTable>>shallowCopy. I would have expected
> it to copy all necessary internal data and maintenance structures, but
> keep a reference to the same keys and values.
shallowCopy is an internal infrastructure method. Always use #copy instead.

--
wbr, ps
sphilippov-at-gmail-com


Reply | Threaded
Open this post in threaded view
|

Re: LookupTable>>shallowCopy a bit too shallow?!

Bernhard Kohlhaas-6
Sergey Philippov wrote:

> Bernhard Kohlhaas wrote:
>
>> Hello all,
>>
>> After an hour of debuggin I have now traced a problem of mine down to
>> an "unexpected behavior" of LookupTable>>shallowCopy. I would have
>> expected it to copy all necessary internal data and maintenance
>> structures, but keep a reference to the same keys and values.
>
> shallowCopy is an internal infrastructure method. Always use #copy instead.
>

Thanks, I'll do that.

I'm wondering though, why then are #shallowCopy (and #postCopy for that
sake) public methods instead of private ones?

Bernhard


Reply | Threaded
Open this post in threaded view
|

Re: LookupTable>>shallowCopy a bit too shallow?!

Sergey Philippov
Bernhard Kohlhaas wrote:

>>
>>> Hello all,
>>>
>>> After an hour of debuggin I have now traced a problem of mine down to
>>> an "unexpected behavior" of LookupTable>>shallowCopy. I would have
>>> expected it to copy all necessary internal data and maintenance
>>> structures, but keep a reference to the same keys and values.
>>
>>
>> shallowCopy is an internal infrastructure method. Always use #copy
>> instead.
>>
>
> Thanks, I'll do that.
>
> I'm wondering though, why then are #shallowCopy (and #postCopy for that
> sake) public methods instead of private ones?
>
postCopy should be private, shallowCopy can be used in your own postCopy
implementation.

--
wbr, ps
sphilippov-at-gmail-com


Reply | Threaded
Open this post in threaded view
|

Re: LookupTable>>shallowCopy a bit too shallow?!

Chris Uppal-3
In reply to this post by Bernhard Kohlhaas-6
Bernhard Kohlhaas wrote:

> I'm wondering though, why then are #shallowCopy (and #postCopy for that
> sake) public methods instead of private ones?

It's very difficult, with only a binary choice between public and private, to
indicate relatively subtle concepts like "this can be called, but it is an
implementation-level method, available for use by subclasses (and client code)
with special needs, but not normally something you'd want to call or think
about".

For a comparable (but reversed) case, much of the WinAPI-level stuff in View is
marked 'private' even though anyone doing Windows-level programming (creating a
new View class, or needing access to features that are not exposed by some View
subclass) will certainly need to call them.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: LookupTable>>shallowCopy a bit too shallow?!

Bernhard Kohlhaas-6
In reply to this post by Sergey Philippov
Sergey Philippov wrote:

>> I'm wondering though, why then are #shallowCopy (and #postCopy for
>> that sake) public methods instead of private ones?
>>
> postCopy should be private, shallowCopy can be used in your own postCopy
> implementation.
>

Well Dolphin has all #postCopy methods as public methods. And its
#postCopy methods never use #shallowCopy, but only #copy.

Regards,
Bernhard


Reply | Threaded
Open this post in threaded view
|

Re: LookupTable>>shallowCopy a bit too shallow?!

Bernhard Kohlhaas-7
In reply to this post by Chris Uppal-3
Hi Chris,

Chris Uppal wrote:

> It's very difficult, with only a binary choice between public and private, to
> indicate relatively subtle concepts like "this can be called, but it is an
> implementation-level method, available for use by subclasses (and client code)
> with special needs, but not normally something you'd want to call or think
> about".

Good point! It would indeed be nice, if there was a category like
"protected" or "restricted" in addition to "public" and "private", but I
assume that is not a part of the Smalltalk tradition.

> For a comparable (but reversed) case, much of the WinAPI-level stuff in View is
> marked 'private' even though anyone doing Windows-level programming (creating a
> new View class, or needing access to features that are not exposed by some View
> subclass) will certainly need to call them.

Thanks, that's useful to know. I haven't done much with views yet, but
I'll keep that in mind, when I start digging deeper into them.

Bernhard