Fellow monks

I am working on a project that requires that I code a destructive iterator to ensure certain cleanup happens. Unfortunately I am getting the destructor called prematurely and trying to see how this happens.

In case it is a bug with the instance, this is on Ubuntu Precise, with perl 5.14.2.

Below is my code. It seems pretty straight-forward to me:

use 5.010;

package it;

sub new {
    my $self = {};
    $self->{_queue} = 1 .. 10;
    bless $self;
}

sub current {
    my $self = shift;
    return $self->{_current};
}

sub next {
    my $self = shift;
    $self->current->destroy if eval { $self->current->can('destroy') };
    delete $self->{_current};
    return unless  @{$self->{_queue}};
    $self->{_current} = it_item->new(shift @{$self->{_queue}}) ;
    return $self->current;
}

sub DESTROY {
    say 'all done';
}

package it_item;

sub new {
    my ($cls, $item) = @_;
    my $self = { _item => $item };
    bless $self, $cls;
}

sub val {
    my ($self) = @_;
    return $self->{_item};
}

sub DESTROY {
    $self = shift;
    warn $self->{_item} . ' destroyed';
}

package main;

my $it = it->new();
# works as expected
$it->next;
$it->next;
while ($it->next){ say $it->current->val };

I would expect to see

1 destroyed
2 destroyed
3 destroyed
4 destroyed
...
all done

But what I actually see is very different

1 destroyed at destroytest.pl line 44.
1 destroyed at destroytest.pl line 44.
1 destroyed at destroytest.pl line 44.
3
1 destroyed at destroytest.pl line 44.
1 destroyed at destroytest.pl line 44.
4
1 destroyed at destroytest.pl line 44.
1 destroyed at destroytest.pl line 44.
5
1 destroyed at destroytest.pl line 44.
1 destroyed at destroytest.pl line 44.
6
1 destroyed at destroytest.pl line 44.
1 destroyed at destroytest.pl line 44.
7
1 destroyed at destroytest.pl line 44.
1 destroyed at destroytest.pl line 44.
8
1 destroyed at destroytest.pl line 44.
1 destroyed at destroytest.pl line 44.
9
1 destroyed at destroytest.pl line 44.
1 destroyed at destroytest.pl line 44.
10
1 destroyed at destroytest.pl line 44.
1 destroyed at destroytest.pl line 44.
all done
1 destroyed at destroytest.pl line 44 during global destruction.
DESTROY created new reference to dead object 'it_item' during global destruction.

Any idea why?


In reply to why am I getting odd behavior on DESTROY by einhverfr

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.