Hi Dr. Dias,

a WeakValueDictionary get's its values collected if they are not referenced strongly. However, the association remains there. This means that when you do:

dictionary := WeakValueDictionary with: 'hello' -> nil copy.

You'll have something like this:

WeakValueDictionary {
�� WeakValueAssociation { key: 'hello', value: yourObject }
}

Once you garbage collect, the value is holding yourObject weakly, so you'll have:

WeakValueDictionary {
�� WeakValueAssociation { key: 'hello', value: nil }
}

But the WeakValueAssociation will still be there.

Apparently, what you want to do is to automatically clean your dictionary. Checking a Pharo60371, I see that WeakValueDictionaries do not implement this... But WeakKeyDictionary does.

Take for example a look at WeakKeyDictionary>>finalizeValues. If you subscribe the WeakKeyDictionary instance to the WeakRegistry, the weak registry will send finalize values to your weak key dictionary and they will eliminate the expired associations. However, #finalizeValues is not implemented in WeakValueDictionary. Maybe we should?

Or maybe you should try with Ephemerons.

Guille

BTW why are you using a copy of nil? you can test it with a plain new Object (i.e., Object new). It took me a couple of extra seconds to realize what you were doing.

On Tue, Feb 21, 2017 at 7:57 AM, phil@highoctane.be <phil@highoctane.be> wrote:
This makes sense, no?

| dictionary |
dictionary := WeakValueDictionary with: 'hello' -> nil copy.
"Smalltalk garbageCollect."
r:={
dictionary values includes: nil.
dictionary at: 'hello'.
dictionary at: 'hello' ifAbsent: [ 'absent' ].
dictionary at: 'hello' ifAbsentPut: [ 'put' ].
}.
r

and I get this anyway when GCing and puttting #x as value

Inline image 1

Maybe checking for emptiness first is needed before going for values include:

Phil


On Mon, Feb 20, 2017 at 11:18 PM, Martin Dias <tinchodias@gmail.com> wrote:
Hi. The answer of:

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

is:

#(true nil nil nil)


Bug or feature? shouldn't the value be considered as absent instead of present (and nil).

cheers,
Mart��n