{"action":"created","issue":{"url":"https://api.github.com/repos/kingpong/perl-Test-Spec/issues/24","labels_url":"https://api.github.com/repos/kingpong/perl-Test-Spec/issues/24/labels{/name}","comments_url":"https://api.github.com/repos/kingpong/perl-Test-Spec/issues/24/comments","events_url":"https://api.github.com/repos/kingpong/perl-Test-Spec/issues/24/events","html_url":"https://github.com/kingpong/perl-Test-Spec/issues/24","id":60332747,"number":24,"title":"Objects cleaned up during global destruction","user":{"login":"JRaspass","id":184356,"avatar_url":"https://avatars.githubusercontent.com/u/184356?v=3","gravatar_id":"","url":"https://api.github.com/users/JRaspass","html_url":"https://github.com/JRaspass","followers_url":"https://api.github.com/users/JRaspass/followers","following_url":"https://api.github.com/users/JRaspass/following{/other_user}","gists_url":"https://api.github.com/users/JRaspass/gists{/gist_id}","starred_url":"https://api.github.com/users/JRaspass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JRaspass/subscriptions","organizations_url":"https://api.github.com/users/JRaspass/orgs","repos_url":"https://api.github.com/users/JRaspass/repos","events_url":"https://api.github.com/users/JRaspass/events{/privacy}","received_events_url":"https://api.github.com/users/JRaspass/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-03-09T11:56:39Z","updated_at":"2015-03-09T23:13:11Z","closed_at":null,"body":"At $WORK, we use Test::Spec with objects that do tear-down in Moo DEMOLISH blocks. These objects are being destroyed in the global destruction phase; this is an issue because you can't assume predictable order of destruction in this phase ( see: http://www.perlmonks.org/?node_id=166791 ).\r\n\r\nThe code below illustrates this issue, $y is destroyed in the RUN phase, $x is destroyed in the DESTRUCT phase ( see: http://perldoc.perl.org/perlvar.html#Variables-related-to-the-interpreter-state ).\r\n\r\n```perl\r\nuse Test::Spec;\r\n\r\nsub foo::DESTROY { warn \"$_[0]{name} ${^GLOBAL_PHASE}\\n\" }\r\n\r\ndescribe a => sub {\r\n    my $x = bless { name => 'x' }, 'foo';\r\n    my $y = bless { name => 'y' }, 'foo';\r\n\r\n    it b => sub {\r\n        # $x is destroyed during global destruction,\r\n        # because there is a circular ref?\r\n        ok ref $x;\r\n    };\r\n\r\n    # $y is destroyed here.\r\n};\r\n\r\nruntests unless caller;\r\n```\r\n\r\nThe above when executed prints:\r\n\r\n```\r\n$ prove -v leak.t \r\nleak.t .. y RUN\r\n\r\nok 1 - a b\r\n1..1\r\nx DESTRUCT\r\n```\r\n\r\nWe would like to find a way to get the same clean-up behaviour that $y exhibits for $x. Our current *hack* involves creating the objects outside of the outer describe and only using weakened references inside."},"comment":{"url":"https://api.github.com/repos/kingpong/perl-Test-Spec/issues/comments/77964640","html_url":"https://github.com/kingpong/perl-Test-Spec/issues/24#issuecomment-77964640","issue_url":"https://api.github.com/repos/kingpong/perl-Test-Spec/issues/24","id":77964640,"user":{"login":"andyjones","id":763877,"avatar_url":"https://avatars.githubusercontent.com/u/763877?v=3","gravatar_id":"","url":"https://api.github.com/users/andyjones","html_url":"https://github.com/andyjones","followers_url":"https://api.github.com/users/andyjones/followers","following_url":"https://api.github.com/users/andyjones/following{/other_user}","gists_url":"https://api.github.com/users/andyjones/gists{/gist_id}","starred_url":"https://api.github.com/users/andyjones/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andyjones/subscriptions","organizations_url":"https://api.github.com/users/andyjones/orgs","repos_url":"https://api.github.com/users/andyjones/repos","events_url":"https://api.github.com/users/andyjones/events{/privacy}","received_events_url":"https://api.github.com/users/andyjones/received_events","type":"User","site_admin":false},"created_at":"2015-03-09T23:13:11Z","updated_at":"2015-03-09T23:13:11Z","body":"`it` blocks are kept around so they can be run later when you call runtests. They won't go out of scope until your program exits so it will keep `$x` alive.\r\n\r\nYou may be able to use before/after blocks as an alternative to weaken?\r\n\r\nI'll think it should be possible for Test::Spec to clear the tests by using an END block but I have been playing for an hour and not had any joy yet.\r\n\r\nI'll take another look at the weekend, hope that is okay."}}