sub positional_mutator(&;$) { my ($worker,$name) = @_; no strict 'refs'; *{$name} = sub { my $self = shift; my $obj; if (defined wantarray) { $obj = $self->copy(); } else { $obj = $self; }; $worker->($obj,@_); } }; positional_mutator { my ($obj,@args) = @_; ... calculate new position here }, 'frobnicate_position';