This came up for some work being done at $JOB, which then went through a complete re-design, making this code no longer necessary. But I thought it was an interesting variation on an iterator.
It probably isn't novel to have this style of iterator wrap multiple sources and present them as a single stream. What makes this different is that the sources are read from on a rotating basis; in this case it was n DBI statement handles which represented data that was split among n different MySQL hosts due to the sheer size of the dataset. For certain (mostly aesthetic) reasons, they wanted the processing stage to interleave the result-sets rather than process them in sequence.
This is based on the wrapped objects being DBI statement handles, and the desired return-format being the sort of hash-ref structure returned by the fetchrow_hashref() method. You can write the next() as you see fit for your encapsulated objects.
For more on clever Perl-ish iterators, see chapter 4 ("Iterators") of Higher-Order Perl by Mark-Jason Dominus (ISBN 9781558607019).
# Usage: my $iter = DbiSthIterator->new($sth1, $sth2, ...); # # while ($row = $iter->next()) { # ...undef signals the exhaustion of the iterator # } package DbiSthIterator; sub new { my ($class, @sth) = @_; bless \@sth, $class; } sub next { my $self = shift; while (my $sth = shift(@$self)) { if (my $row = $sth->fetchrow_hashref()) { push(@$self, $sth); return $row; } else { # Leaving the exhausted $sth out of the queue next; } } undef; } 1;
In reply to Variation on the "Higher Order Perl" Iterator Pattern by rjray
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |