lua-users home
lua-l archive

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


I just finished reading Diego Nehab's page on "Finalized Exceptions" on the
Lua Users' Wiki. (http://lua-users.org/wiki/FinalizedExceptions) I like the
overall approach and something like it might be a good idea for inclusion in
Lua 5.1. I would add it myself to my version, but I'm cautious about
namespace clashes.

Here are some general reactions:

* I'm a little unclear as to where the finalized part comes in with respect
to exceptions -- i.e., the title isn't immediately obvious to me.

* The notion of generating a new finalization function and then running
everything else through it feels a little heavy for coding. Yes, it beats
many of the present alternatives, but it cries out for an easy way to wrap a
block of statements in a single try.

* Is my impression correct that try does not work if the code being wrapped
should happen to throw an exception? In other words, it only works if
everything is well behaved?

* One other pattern I use routinely works like this:

get = protect(function( host, path )
    return withConnection( host, 80, function( c )
        assert( c:send( "GET " .. path .. " HTTP/1.0\r\n\r\n" ) )
            --  send the request
        -- get headers
        local h = {}
        while 1 do
            local l = assert( c:receive() )
            if l == "" then break end
            table.insert( h, l )
        end
        -- get body
        local b = assert( c:receive( "*a" ) )
        return h, b
    end )
    return b, h
end)

Where we define:

local function pack( success, ... )
    return success, arg
end

withConnection = function( host, port, func )
    local c = assert( connect( host, port ) )
    local success, results = pack( pcall( func, c ) )
    c:close()
    if not success then error( results[ 1 ] ) end
    return unpack( results )
end

(I left the protect in on get, but it should probably really go on
withConnection in which case it wouldn't really be needed on get.)

This basically mirrors C++ constructor/destructor error handling semantics.
It creates exactly as many closures, but it makes fewer calls to pcall.

Mark