Skip Menu |
Report information
Id: 127243
Status: open
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: autarch <autarch [at] urth.org>
Cc:
AdminCc:

Severity: (no value)
Tag: (no value)
Platform: (no value)
Patch Status: (no value)
VM: (no value)



Subject: DESTROY is not called on interpreter exit
Download (untitled) / with headers
text/plain 730b
Here's an example which might demonstrate why this is important: class C { has @.threads; method foo { @!threads = (^10).map: { Thread.start( name => $_, sub { sleep 1; say $*THREAD.name; } ) }; say @!threads; }; submethod DESTROY { say 'bye'; .finish for @!threads; }; }; my $c = C.new; $c.foo; exit 0; While there are various workarounds, it seems like that all force the _user_ of the class to explicitly account for the need to cleanup threads created by C. It seems like a class should be fully self-contained and capable of cleaning up after itself.
Download (untitled) / with headers
text/plain 340b
hoelzro++ pointed me to http://irclog.perlgeek.de/perl6/2015-07-22#i_10938226 for some relevant discussion. FWIW, I think the idea of having teardown enabled by default with a switch to disable it from inside code is reasonable(-ish), although there'd have to be a strong culture of "never do this inside a module you want others to use".
Subject: Re: [perl #127243] DESTROY is not called on interpreter exit
Date: Tue, 12 Jan 2016 09:48:26 +0100
To: "Dave Rolsky (via RT)" <perl6-bugs-followup [...] perl.org>
From: Elizabeth Mattijsen <liz [...] dijkmat.nl>
Download (untitled) / with headers
text/plain 1.5k
Show quoted text
> On 12 Jan 2016, at 04:49, Dave Rolsky (via RT) <perl6-bugs-followup@perl.org> wrote: > > # New Ticket Created by Dave Rolsky > # Please include the string: [perl #127243] > # in the subject line of all future correspondence about this issue. > # <URL: https://rt.perl.org/Ticket/Display.html?id=127243 > > > > Here's an example which might demonstrate why this is important: > > class C { > has @.threads; > method foo { > @!threads = (^10).map: { > Thread.start( > name => $_, > sub { > sleep 1; > say $*THREAD.name; > } > ) > }; > say @!threads; > }; > submethod DESTROY { > say 'bye'; > .finish for @!threads; > }; > }; > > my $c = C.new; > $c.foo; > exit 0; > > While there are various workarounds, it seems like that all force the _user_ of the class to explicitly account for the need to cleanup threads created by C. It seems like a class should be fully self-contained and capable of cleaning up after itself.
At exit, all threads are cleaned up automatically anyway, so I don’t really think this is a problem in *this* case. More generally, I think it would be nice if an import would be able to import a LEAVE phaser into the scope: this then would allow code to be executed whenever the importing scope would be left (which an exit would do). $ 6 'LEAVE say "goodbye"; exit’ $ 6 'LEAVE say "goodbye"’ goodbye OTOH, it looks like exit() is not honouring LEAVE phasers either… hmmmm…. Liz
Download (untitled) / with headers
text/plain 883b
On Tue Jan 12 00:48:59 2016, elizabeth wrote: Show quoted text
> > At exit, all threads are cleaned up automatically anyway, so I don’t > really think this is a problem in *this* case.
Well, it is a problem if your program needs to do something with the thread as part of the cleanup, like set an exit status based on the values that the threads return or something. Show quoted text
> More generally, I think it would be nice if an import would be able to > import a LEAVE phaser into the scope: this then would allow code to be > executed whenever the importing scope would be left (which an exit > would do). > > $ 6 'LEAVE say "goodbye"; exit’ > $ 6 'LEAVE say "goodbye"’ > goodbye > > OTOH, it looks like exit() is not honouring LEAVE phasers either… > hmmmm….
An injected LEAVE would be a sort of okay solution, but it really seems like running DESTROY would be the least surprising thing to do.
Download (untitled) / with headers
text/plain 533b
On Tue Jan 12 07:11:20 2016, autarch wrote: Show quoted text
> An injected LEAVE would be a sort of okay solution, but it really > seems like running DESTROY would be the least surprising thing to do.
I take the first part of this statement back. An injected LEAVE really doesn't work for anything object-related. There's nothing to say that the lexical scope which creates an object is the scope where the object lives: my $o; { $o = C.new } Injecting a LEAVE there would just make a huge mess. There's really no substitute for DESTROY.


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org