Fwd: [pubsub] hard references instead of weak ones

5 views
Skip to first unread message

oliver

unread,
Aug 26, 2015, 11:59:56 AM8/26/15
to pypubsub_dev

On Wed, Aug 26, 2015 at 6:44 AM, Jérôme Laheurte <fra...@gmail.com> wrote:

> Le 25 août 2015 à 23:12, oliver <oliver.s...@gmail.com> a écrit :
>
> You are correct. Weak referencing is essential otherwise you will find you have to manually manage lifecycle of your objects that were listeners, just because they were registered as listeners, gets tedious. The pro is that when a listener is no longer used by the app, pubsub automatically forgets it. The con is that when a listener is no longer used by the app, pubsub automatically forgets it :)

Somehow related to this, I regularly find myself having to maintain a cache of references to a locally-defined callback in order to do curryfication. Dummy example:

def foo(self):
    self._cache = set()
    for index, obj in enumerate(objs):
        self._bind(index, obj)

def _bind(self, index, obj):
    def cb():
        self.objChangedAtIndex(index)
    obj.subscribe(cb, ‘changed’)
    self._cache.add(cb) # Or else it gets dereferenced

def objChangedAtIndex(self, index):
    pass

Of course it’s a PITA to maintain the cache if I don’t want my callbacks to live forever. What I’d like to be able to do is « obj.subscribe(self._objChangedAtIndex, moreArgs=(index,)) » or something. I couldn’t find anything in the documentation regarding this use case, did I miss something ?

Cheers
Jérôme


You didn't miss anything. You would have to pass curried args by name, just like you have to pass named arguments when sending a message (if only to support currying non-contiguous positional parameters). Subscribe() currently takes a listener callable and topic name, so the API should be extendable with a **kwargs, allowing you to do this: 

def listen(arg1, arg2, arg3):
    pass
obj.subscribe(listen, 'topic', arg1=1, arg3=3)
pub.sendMessage('topic', arg2='a')  # calls listen(1, 'a', 3)
pub.sendMessage('topic', arg2='b')  # calls listen(1, 'b', 3)
pub.sendMessage('topic', arg2='c')  # calls listen(1, 'c', 3)

Would that work? The objects in the dict would have to be strong referenced which is not great (I would prefer to stick with the policy that when an object is no longer used outside of pubsub, it can be destroyed). So you'd have to be careful what you bind, although at most the "artificial" lifetime due to strong referencing by pubsub would be that of the listener, perhaps not too bad. 

--
Oliver
Author of these Open Source: PyPubSub, Lua-iCxx, iof
Regular contributor on StackOverflow




--
Oliver
Author of these Open Source: PyPubSub, Lua-iCxx, iof
Regular contributor on StackOverflow

Reply all
Reply to author
Forward
0 new messages