Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
use strict;
use warnings;
{
package LvalueArray;
use base 'Tie::Array';
sub TIEARRAY {
my ($class, $sub, $params, $afters) = @_;
my $self = bless [ $sub, $params, $afters ], $class;
}
sub STORE {
$_[0]->[4][$_[1]] = $_[2];
}
sub CLEAR {
$_[0]->[4] = [];
}
sub EXTEND {
$#{$_[0]->[4]} = $_[1]-1;
}
sub FETCHSIZE {
$_[0]->run;
scalar @{$_[0]->[3]};
}
sub FETCH {
$_[0]->run;
$_[0]->[3][$_[1]];
}
sub run {
my ($sub, $params, $afters, $result, $store) = @{$_[0]};
return if $result;
if ($store) {
$_[0]->[3] = [($sub->(@$params)) = @$store];
}
else {
$_[0]->[3] = [($sub->(@$params))];
}
for my $after (@$afters) {
$after->(@$params);
}
}
sub DESTROY {
$_[0]->run;
}
}
my @foo;
my $foo;
sub foo :lvalue {
warn "foo running\n";
@foo;
}
sub wrap :lvalue {
tie my @array, 'LvalueArray', \&foo, \@_, [sub { warn "after running\n" }];
@array;
}
(foo()) = (10, 11);
warn "running with after\n";
(wrap()) = (12,13);
warn "running again\n";
warn wrap();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment