Hi, > >When removing hooks they are identified by coderef, so this is WRONG: > > > >$win->Hook(WM_MOVE, sub { print "moved!" }); > >$win->UnHook(WM_MOVE, sub { print "moved!" }); > > > >In that case, UnHook will return false and the hook will not be removed > >because the codref passed to the UnHook call will be different to the one > >passed to Hook. You should do it like this: > > > >$movedsub = sub { print "moved!\n" }; > >$win->Hook(WM_MOVE, $movedsub); > >$win->UnHook(WM_MOVE, $movedsub); > > I'm sorry but, from the outside, doesn't this seem slightly illogical?
No? From what you wrote below there might be some misunderstanding here... > What happens if you do: > $win->Hook(WM_MOVE, $mysub); > $win->Hook(WM_MOVE, $myothersub); Two hooks are assigned. When $win receives WM_MOVE, $mysub is called, then $myothersub is called. > or even using the same handler for two windows: > $win->Hook(WM_MOVE, $mysub); > $win2->Hook(WM_MOVE, $mysub); > Would that result in weirdness? No, when $win receives WM_MOVE, $mysub is called. when $win2 receives WM_MOVE, $mysub is called. Hooklists are per-object. It works as you would expect. If you want to remove $mysub handler from $win2, you'd do $win2->UnHook(WM_MOVE,$mysub); - literally "remove the $mysub handler from $win2's list of handlers for WM_MOVE". > Would it not be more logical to key the hook by the $win and the message > (WM_MOVE) rather than the handler coderef? No. The hook is ALREADY keyed by the $win, we're (pseudo) object oriented here. There is an individual array of handlers for every message for every window/widget. This is to allow you to add several hooks to ONE message in a specific window. The advantages of this include: 1) 3rd party modules can get a window object passed to them and assign and unassign their own hooks without breaking the users own hooks, since every hook you remove is identified by the coderef of the handler, there is no possibility that a 3rd party module could accidentally remove one of the users own hooks. 2) You can temporarilly make one window message call an additional handler, without first having to remove the original handler and re-add the original handler afterwards. 3) It's just generally versatile. Also, the semantics are not strange if you do something like this: $win->Hook(WM_MOVE,\&handler); $win->UnHook(WM_MOVE,\&handler); since \&handler always returns a coderef of the same value. Hope that helps, Steve