[Pharo-dev] WeakValueDictionary: shouldn't be "absent" after GC?

Guillermo Polito guillermopolito at gmail.com
Wed Feb 22 07:52:49 EST 2017


On Wed, Feb 22, 2017 at 12:57 AM, Martin Dias <tinchodias at gmail.com> wrote:

> Hi all
>
> Phil:
> I'm sorry, didn't get what you point with the code snippet. The copy of
> the Symbol is the same instance, that I think it's nto GCed.
>
> Guille:
> Yes, I knew the internals of the WeakValueDictionary but asked about the
> API.
>

Ah, ok, I only understood that you did not get why it was like that. :)


> What I don't know is about using WeakRegistry
>

This is just needed to do the cleanup of the expired associations.


> and Ephemerons.
>

This is a completely different thing. There is an EphemeronRegistry in the
image, but it does not propose at:/at:ifAbsent: messages. It just holds
Ephemerons.

I'll check WeakKeyDictionary.
>

If you need to hold weakly the values, then this is not what you're looking
for, isn't it?


>
> I understand the idea of "explicit control of magic", but not sure if I
> understand concretely. Do you mean to implement something like
> WeakValueDictionary>>register which will not be executed by #initialize,
> so the user can decide to register. Am I right?
>

Yep. I would even call it:

 registerForCleanup

Like that it is explicit that you're doing it, and that it may incur into
some performance degradation of the entire system.


>
> Denis:
> +1 WeakSet behavior is really confusing! In thte case of
> WeakValueDictionary I didn't check for inconsistencies but was only annoyed
> but it's behavior.
>
> Guille and Denis:
> Instead of using SetElement or cleaning up the empty
> WeakValueAssociations, what I first thought is to internally consider an
> association with nil as absent. I mean, modify or override some methods
> soem when there is an WeakValueAssociation with value == nil it considers
> it's absent. Concretely, I'd expect:
>

Well, the idea of the SetElement is that you may want to have `nil` as a
valid value in your dictionary. Otherwise, you cannot do:

WeakValueDictionary new
   at: 'key' put: nil;
   at: 'key' --> error???

We can discuss if it is useful or not, but as with sets, before people used
to check if the inserted element was nil beforehand to have the expected
behavior...


> | dictionary |
> dictionary := WeakValueDictionary with: 'hello' -> 'world' copy.
> Smalltalk garbageCollect.
> {
> dictionary values includes: nil. *---> false *
> dictionary at: 'hello'. * ---> NotFound signal*
> dictionary at: 'hello' ifAbsent: [ 'absent' ].* ---> 'absent'*
> dictionary at: 'hello' ifAbsentPut: [ 'put' ]. *---> 'put'*
> }
>

I agree that we may review the API. At least #at:, #at:ifAbsent: and
#at:ifAbsentPut: should behave similarly.

In any case, we could see how to improve EphemeronRegistry or even
implement an EphemericDictionary that would replace the WeakValueDictionary.


>
> It's better if I give some context. Look this simplified version of my use
> case:
>
> MyUI>>
> morphAt: key
> cache ifNil: [ cache := WeakValueDictionary new ].
>  ^ cache at: key ifPresent: [:cachedValueOrNil | cachedValueOrNil
> ifNotNil: [ cachedValueOrNil ] ifNil: [ cache at: entryReference put: (self
> newMorph: key) ] ] ifAbsent: [ cache at: entryReference put: (self
> newMorph: key) ]
>
> I'd like to only send #newMorph: in ifAbsent: and to avoid the
> ifNotNil:ifNil:
> Like this:
>
> morphAt: key
> cache ifNil: [ cache := WeakValueDictionary new ].
>  ^ cache at: key ifAbsent: [ cache at: entryReference put: (self
> newMorph: key) ]
>
> :-)
>
> Martín
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pharo.org/pipermail/pharo-dev_lists.pharo.org/attachments/20170222/322c598a/attachment.html>


More information about the Pharo-dev mailing list