On 23 April 2013 18:02, Sean P. DeNigris <sean@clipperadams.com> wrote:of course, because the home context (will be the method below) of
> Igor Stasenko wrote
>> but what you expecting?
>> you refer to 'self' multiple times. sure thing it cannot be GC-ed,
>> neither process will die because
>> of plenty of references on stack.
>> Even block closure which you creating for fork will have home context
>> which keeps reference to 'self',
>> e.g. receiver.
>
> I'm expecting magic apparently because I am stupid when it comes to
> processes ;) I changed all the "self"s to array first, which also didn't
> work, but then I read your statement about the home context...
>
> Luc's class-side trick seems to work:
> Timer>>start
>
> � � � � | array |
> � � � � array := WeakArray with: self.
> � � � � process := self class createProcessFor: array. "tried passing self here,
> but it seemed to keep the process around"
>
closure captures method's arguments,
and holding them strongly..�
it is not apparent to me why this is common use case. :)
> Timer class>>createProcessFor: aWeakArray
>
> � � � � [ [ aWeakArray first notNil ] whileTrue: [
> � � � � � � � � | timer |
> � � � � � � � � aWeakArray first interval asDelay wait.
> � � � � � � � � "We have to check again if the timer was garbage collected during the
> wait"
> � � � � � � � � aWeakArray first ifNotNil: [
> � � � � � � � � � � � � aWeakArray first value: aWeakArray first value + 1.
> � � � � � � � � � � � � aWeakArray first announcer announce: (TimerValueChanged to: aWeakArray
> first value) ] ] ] fork.
>
> Wow, it would seem that an object using a process internally that is only
> valid when the object is around is a fairly common use case. I can't believe
> how complicated this is :/
>
you can also simply pass a copy of 'self' to process.
as long as copy accessing same announcer, your ticker process will
work perfectly.
then all you would need to do is:
| copy |
copy := self copy.
process := self class createProcessFor: copy.
WeakRegistry default add: self executor: copy.
and implement:
finalize
� process terminate.
� process := nil.
Then createProcessFor: will be simple:
Timer class>>createProcessFor: timer
�[
[ timer wait. " make Demeter a bit happier"
� timer tick. "this should increment counter and announce TimerValueChanged,
� � � � � � � � � � �like that we're not make Demeter unhappy"
] whileTrue � ] fork.
(actually , to make mr.Demeter completely happy, i would do
� [ timer waitAndTick ] whileTrue.
)
and, tick, will be something like that:
tick
� process ifNil: [ ^ false ].
� self incrementCounter.
� self announce: (MyGreatAnnouncement with: whatever).
� ^ true.
cheerz :)
> -----
> Cheers,
> Sean
> --
> View this message in context: http://forum.world.st/Terminating-a-Process-when-an-object-dies-tp4683036p4683144.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>
--
Best regards,
Igor Stasenko.