On Wed, Feb 22, 2017 at 9:52 AM, Guillermo Polito <[email protected]
> wrote:

>
>
> On Wed, Feb 22, 2017 at 12:57 AM, Martin Dias <[email protected]>
> 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.
>
>
OK, I wrote several tests for the expected behavior and fixed
WeakValueDictionary. Anyway, not sure if it's convenient to integrate it in
Pharo 6 or in any version... maybe it's just OK to check for nils at
user-level as currently, and do not change it. I had to use SetElement else
tests didn't pass.

https://pharo.fogbugz.com/f/cases/19746/WeakValueDictionary-has-counter-intuitive-behavior




> 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
>>
>
>

Reply via email to