lua-users home
lua-l archive

Re: PATCH: Fully Resumable VM (yield across pcall/callback/meta/iter)

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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

AltStyle によって変換されたページ (->オリジナル) /