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
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |