Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DESTROY is not called on interpreter exit #5042

Open
p6rt opened this issue Jan 12, 2016 · 6 comments
Open

DESTROY is not called on interpreter exit #5042

p6rt opened this issue Jan 12, 2016 · 6 comments
Labels
RFC Request For Comments

Comments

@p6rt
Copy link

p6rt commented Jan 12, 2016

Migrated from rt.perl.org#127243 (status was 'open')

Searchable as RT127243$

@p6rt
Copy link
Author

p6rt commented Jan 12, 2016

From @autarch

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.

@p6rt
Copy link
Author

p6rt commented Jan 12, 2016

From @autarch

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

@p6rt
Copy link
Author

p6rt commented Jan 12, 2016

From @lizmat

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-archive.perl.org/perl6/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

@p6rt
Copy link
Author

p6rt commented Jan 12, 2016

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Jan 12, 2016

From @autarch

On Tue Jan 12 00​:48​:59 2016, elizabeth wrote​:

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.

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.

@p6rt
Copy link
Author

p6rt commented Jan 13, 2016

From @autarch

On Tue Jan 12 07​:11​:20 2016, autarch wrote​:

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.

@p6rt p6rt added the RFC Request For Comments label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFC Request For Comments
Projects
None yet
Development

No branches or pull requests

1 participant