I should have mentioned that substr makes a copy when $rec1->() is called. That's unavoidable. You can't extract a string from another without making the new string. However, the copy is only done when $rec1->() is executed.
If that's a problem, you could extract small chunks at a time. For example, only 100 (by default) chars are duplicated at any given time.
sub new_callback_accessor {
my $start = $_[0];
my $end = $_[1];
my $data_ref = \$_[2]; # Avoid making a copy.
return sub {
my ($callback, $blk_size) = @_;
local *_;
$blk_size = 100 unless defined $blk_size;
$blk_size = $end-$start unless $blk_size;
my $ofs = $start;
my $len = $end-$start;
while ($len) {
$blk_size = $len if $blk_size > $len;
$_ = substr($$data_ref, $ofs, $blk_size);
$callback->();
$ofs += $len;
$len -= $blk_size;
}
};
}
{
my $data = ...;
my $start1 = ...; # Calculate start from map.
my $end1 = ...; # Calculate end from map.
my $rec1 = new_callback_accessor($start1, $end1, $data);
$rec1->(sub { print });
print("\n");
}
Untested.
|