2467c2467 < $param_map->{$param}[HTML::Template::LOOP::PARAM_SET] = [@{$value}]; --- > $param_map->{$param}[HTML::Template::LOOP::PARAM_SET] = $value; 2612c2612 < eval { $result .= $line->output($x, $options->{loop_context_vars}); }; --- > eval { $line->output($x, $options->{loop_context_vars},\$result); }; 2885a2886,2888 > my $result; > my $blank = ""; > $result = shift or $result = \$blank; 2906c2908 < $result .= $template->output; --- > ${$result} .= $template->output; 2914c2916 < return $result; --- > return ${$result}; #### package Tie::Array::SubIterator; use base Tie::Array; sub TIEARRAY { my $class = shift; my %in = @_; $in{'length'} = -1 unless $in{'length'} && $in{'length'} =~ /^\d$/; die "Expected coderef for next option" unless ref($in{'next'}) eq "CODE"; die "Expected coderef for determine_end option" unless !defined($in{'determine_end'}) or $in{'length'} < 0 or ref($in{'determine_end'}) eq "CODE"; $in{'determine_end'} = sub { return defined(+shift->{'last_result'}) ? 0:1; } if (!$in{'determine_end'} && $in{'length'} < 0); $in{'last_counted'} = 0; $in{'ended'} = 0; my $self = bless \%in, $class; eval { $self->{'last_result'} = $self->{'next'}->($self,0) if $self->{'length'} < 0; }; $self->{'ended'} = 1 if $@; return $self; } sub FETCH { my $self = shift; return $self->{'next'}->($shift,@_) if ($self->{length} > -1); my $last = $self->{'last_result'}; eval { $self->{'last_result'} = $self->{'next'}->($self,++$_[0]) unless $self->{'ended'}; }; $self->{'ended'} = 1 if $@; return $last; } sub FETCHSIZE { $self = shift; return $self->{'length'} if $self->{'length'} > -1; ++$self->{'last_counted'} unless ($self->{'ended'}) || ($self->{'ended'} = $self->{determine_end}->($self)); $self->{'last_counted'}; } sub DESTROY { my $self = $_[0]; $self->{destroy}->(@_) if ref($self->{destroy}) eq "CODE"; } 1; #### #!/usr/bin/perl -w use strict; use Tie::Array::SubIterator; use HTML::Template; use Devel::Size qw(total_size); my @array= (1..10_000); sub next { my $self = shift; return undef if $_[0] > $#array; return { num => $array[$_[0]], added => $array[$_[0]]+10, subtracted => $array[$_[0]]-10 }; } my @old_method; push @old_method, { "num" => $_, "added" => ($_ + 10), subtracted => $_-10 } for (@array); print "old: ", total_size(\@old_method),$/; print "new: ", total_size(\@array),$/; tie my @data, "DMN::TieArrayForeach", next=>\&next; my $tmpl = q|

|; my $template = HTML::Template->new(scalarref => \$tmpl); $template->param(data => \@old_method,bob=>"outer area"); my $one = $template->output(); $template->param(data => \@data,bob=>"outer area"); my $two = $template->output(); print "identical$/" if $one eq $two; ##
## old: 2145624 new: 240056 identical