[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: PATCH: Fully Resumable VM (yield across pcall/callback/meta/iter)
- From: Mark Hamburg <mhamburg@...>
- Date: Wed, 16 Feb 2005 23:43:19 -0800
I had been contemplating building something like Cocoa's autorelease pool
mechanism to work around the inability to yield across a pcall. (So many
ideas for code to write. So little time to actually write code.)
However, given a cheaper, yield-friendly pcall, it may be just as easy to
write:
function processWithFinalizer( finalizer, success, ... )
pcall( finalizer )
if success then
return ...
else
error( select( 1, ... ), 2 )
end
end
function withFileDo( path, func )
local file = assert( io.open( path ) )
return processWithFinalizer(
function()
file:close()
end,
pcall( func, file ) )
end
Interestingly, the RVM version seems to fix an error in Lua 5.1 in which in
the following code the value of file in the above finalizer has been rebound
to 1:
withFileDo( myFilePath, -- insert valid file path here
function( f )
print( f )
return 1, 2, 3
end )
Mark
P.S. One could actually reduce the number of closures being generated while
running this code by doing various things like passing an extra argument to
processWithFinalizer or by writing a custom version that works specifically
with files. That can all be encapsulated as follows:
function makeProcessWithFinalizer( finalizer )
-- returns a function taking an argument for the finalizer plus
-- the results to pass back up from a pcall
return function( finalizerArg, success, ... )
pcall( finalizer, finalizerArg ) -- skip the pcall if gutsy
if success then
return ...
else
error( select( 1, ... ), 2 )
end
end
end
----
local fileFinalizer = makeProcessWithFinalizer(
function( file ) file:close() end )
function withFileDo( path, func, ... )
-- Calls func( file, ... ) where file is the result of
-- opening the path. Closes the file when done.
local file = assert( io.open( path ) )
return fileFinalizer( file, pcall( func, file, ... ) )
end