Reputation: 40319
Suppose I have a function that returns a closure:
sub generator
{
my $resource = get_resource();
my $do_thing = sub
{
$resource->do_something();
}
return $do_thing;
}
# new lexical scope
{
my $make_something_happen = generator();
&$make_something_happen();
}
I would like to be able to ensure that when $make_something_happe
n is removed from scope, I am able to call some $resource->cleanup();
Of course, if I had a class, I could do this with a destructor, but that seems a bit heavyweight for what I want to do. This isn't really an "object" in the sense of modelling an object, it's just a functiony thing that needs to execute some code on startup and immediately prior to death.
How would I do this in Perl( and, out of curiosity, does any language support this idea)?
Upvotes: 2
Views: 153
Reputation: 19
I think I understand your question. In my case I want:
* A global variable that may be set at any point during the script's runtime
* To last right up to the end of the life of the script
* Explicitly clean it up.
It looks like I can do this by defining an END block; It will be run "as late as possible". You should be able to do your $resource->cleanup(); up in there.
More here: http://perldoc.perl.org/perlmod.html#BEGIN%2c-UNITCHECK%2c-CHECK%2c-INIT-and-END
The begincheck program on that page has the code.
Upvotes: -1
Reputation: 132896
I'd just use a class for this. Bless the subroutine reference and still use it like you are. The get_resource
then uses this class. Since I don't know what that looks like, I'll leave it up to you to integrate it:
package Gozer {
sub new {
my( $class, $subref );
bless $subref, $class;
}
sub DESTROY {
...; #cleanup
}
}
If every thing can have it's own cleanup, I'd use the class to group two code refs:
package Gozer {
sub new {
my( $class, $subref, $cleanup );
bless { run => $subref, cleanup => $cleanup }, $class;
}
sub DESTROY {
$_[0]{cleanup}();
}
}
In Perl, I don't think this is heavyweight. The object system simply attaches labels to references. Not every object needs to model something, so this is a perfectly fine sort of object.
It would be nice to have some sort of finalizers on ordinary variables, but I think those would end up being the same thing, topologically. You could do it with Perl as a tie
, but that's just an object again.
Upvotes: 5