perlquestion jbert <p>Hi.</p> <p>I've recently had a bunch of "fun" chasing down leaks in code (mine and others) caused by accidental capture of variables in callbacks.</p> <p>e.g. something like:</p> <code> sub foo { my $self = shift; $self->do_something(on_success => sub { do_stuff(); $self->log("done stuff"); do_more_stuff(); $self->log("done more stuff"); }); </code> <p>Assuming that do_something hides the callback within $self, we've just created a cycle which if it doesn't get cleared (e.g. on an error path) will cause a leak (could leak mem, could leak other resources such as network connections. badness.)</p> <p>Note that the logging could have been added casually, and doesn't look evil on a review diff.</p> <p>One idea being bounced around here would be a pragma which declared "I don't want any vars to be captured implicitly" and a way of marking which vars are ok to capture.</p> <p>The thinking is that this would make it clear and explicit what vars are being captured, so it is easy to see them and reason about them. Something like:</p> <code> use NoClose; sub foo { # Still a cycle, but now a more obvious one! $self->do_something(on_success => sub : capture('$self') { do_stuff(); $self->log("done stuff"); do_more_stuff(); $self->log("done more stuff"); }); </code> <p>With the idea being that any vars which a closure would capture would be compile-time errors unless they are referenced in the 'capture' attribute.</p> <p> this madness? And has it already been implemented? Or do people resolve this pain in a different way?</p> <p>(I know about weak refs, the issue is more about making it easy to know what to weaken.)</p> <p>[Edit, added comment to code to emphasise that this doesn't prevent cycles, just makes them more visible.</p>