Syntactic sugar for scope closing hook?

S

Steve Roscio

Howdy -

I have a module where its functions work in pairs: an opening and
closing pairs. Because it's likely that these functions will be used
where the programmer also uses exceptions (eval/die), or just wants to
be lazy, it's important that the close function is always called when
exiting the enclosing scope. I find it tedious to track down every
possible exit path and include the closure.

The simple way to achieve this is to create and object and have a
DESTROY method for it:
{
my $trak = function_returning_some_object (args...);
. . .
} # DESTROY() method called here, invokes close function

That's OK, but I'd like to take it to the next level and make it
syntactically look nicer. Some sugar, if you will. I want to just do this:

{
blah args...; # blah creates object in *current* scope
. . .
} # Closure for 'blah' object called

How can I do this?

I've had some success by stuffing a closure (with a DESTROY) into the
caller(1)'s symbol glob. But that only handles the case when the scope
is the enclosing sub. How do I do this for local scopes created simply
by pairs of { }'s ?

I've also done source filters that simply convert the sugar-coated form
into the primitive form. But that feels evil.

Thanx in advance,
- Steve

PS: Sorry, I know I'm not explaining this well. I hope you can get the
gist of it.
 
C

C.DeRykus

Howdy -

I have a module where its functions work in pairs: an opening and
closing pairs. Because it's likely that these functions will be used
where the programmer also uses exceptions (eval/die), or just wants to
be lazy, it's important that the close function is always called when
exiting the enclosing scope. I find it tedious to track down every
possible exit path and include the closure.

The simple way to achieve this is to create and object and have a
DESTROY method for it:
{
my $trak = function_returning_some_object (args...);
. . .
} # DESTROY() method called here, invokes close function

That's OK, but I'd like to take it to the next level and make it
syntactically look nicer. Some sugar, if you will. I want to just do this:

{
blah args...; # blah creates object in *current* scope
. . .
} # Closure for 'blah' object called

How can I do this?

I've had some success by stuffing a closure (with a DESTROY) into the
caller(1)'s symbol glob. But that only handles the case when the scope
is the enclosing sub. How do I do this for local scopes created simply
by pairs of { }'s ?

I've also done source filters that simply convert the sugar-coated form
into the primitive form. But that feels evil.

IIUC Scope::Guard may be able to help:

use Scope::Guard;

{
my $cleanup = sub { print "cleaning up...\n"; };
my $guard = Scope::Guard->new( $cleanup );
}
 
K

Kevin Ryde

Steve Roscio said:
syntactically look nicer

There's quite a few of those finalizer things. Hook::Scope or
B::Hooks::EndOfScope might do enough syntax for you. Scope::Upper might
help create such a thing. The basic ones include AtExit, Guard and
Sub::ScopeFinalizer, but personally I've found the little Scope::Guard
already mentioned enough.
 
S

Steve Roscio

Thanx guys - that's what I needed. I like the XS methods done by Guard
and B::Hooks::EndOfScope. But I'm not yet very comfortable writing my
own XS so I'll use Scope::Upper until I am.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,710
Latest member
bernietqt

Latest Threads

Top