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"); }