I am trying to figure out the best way for an object to replace itself using a method, such that I can write while($object->load_next) rather than foreach(@objects). The only solution I have figued out is for the method to de-reference its own object and overwrite the object's hash, but this seems wrong. Details:

I have a persistence superclass I use to store my objects. One of its methods is ->list, which compiles a list of all stored instances of a particular class (i.e. every record in a database table). The method ->list will return an array if you wantarray, but otherwise it returns an object of the appropriate class with a method called ->load_next.

Calling ->load_next once loads then first stored instance of the class into the object. Calling it subsequently overwrites the object with the next stored class instance, until all stored class instances are exhausted, at which point the method returns undef.

I believe this is a fairly common pattern for object oriented design. In fact, it is modeled on the methods .List and .GetNext used by an experienced VB programmer.

But I'm not sure whether I know how to implement this properly in Perl. The method ->load_next can't simply overwrite the object self-reference it is passed, since such a change would only affect the method's own *copy* of the reference. Instead, I de-reference the object and overwrite its internal hash with the hash of the next object in the queue, sort of like an object copying method.

(Unlike a typical self-copy method, I don't have to re-bless the object, since existing referneces to the hash are already blessed.)

Is this the only way to pull this off? My method will not work for blessed arrays or scalars, and as I mentioned the method ->load_next is part of a superclass I want to use widely.

Example of the method in use, followed by actual code for ->load_next:

The method in use:

my $notes = My::Dashboard::Note->list; while ($notes->load_next){ print $notes->headline, $notes->created, $notes->body; }

The load_next method:

sub load_next{ my ($self, %arguments) = @_; my @next = @{$self->storage_next_list}; my $new_self = shift @next or return; %{$self} = %{$new_self}; $self->storage_next_list(list=>\@next); return $self; } sub storage_next_list{ my ($self, %arguments) = @_; $self->{storage}{next} = $arguments{list} if exists $arguments{list} +; return $self->{storage}{next}; }

In reply to An object replacing itself by ryantate

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.