On Tue, Feb 21, 2017 at 10:37 AM, Denis Kudriashov <dionisiydk@gmail.com> wrote:
Hi.
2017-02-21 9:44 GMT+01:00 Guillermo Polito <guillermopolito@gmail.com>:
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.
For me what you describe is implementation details and users should not think about it at all.
Of course it is an implementation detail. I'm just describing how it works (and thus, how it does not work). I never said it was a good or bad approach. I agree ifAbsent~ messages should work with collected values by "absent
branch". It is intuitive.
To support it correctly we can use approach of Set which uses #asSetElement to store items. Then we can easily distinguish nil from absent value. Real nil value will happen only by garbage collection. But I am wondering WeakSet not uses SetElement approach directly and instead it uses special flag object. Maybe it should be fixed too.
But in any case, whatever the alternative you give users, they must understand the tradeoff. If all Weak*Dictionaries were subscribed by default to the weak registry for cleanup, that would provoke a lot of overhead during garbage collection. Magic is good in some cases, but when you're dealing with low level stuff explicitly (like instantiating a Weak*Dictionary) I prefer to control some of that magic explicitly.