lua-users home
lua-l archive

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


Why we need extra functionality if it could be done with existing one?

>         do
>           -- --------------------------------------------------------------
>           -- 'scope' is like 'local' in that the variable is local to the
>           -- current scope, but unlike 'local', the variable is closed at
>           -- the end.  When we leave the current scope, each variable
>           -- declared as a 'scope' is checked for a __close metamethod, and
>           -- if it exists, it is called; otherwise, nothing happens.
>           -- --------------------------------------------------------------
>
>           scope f,err = io.open("foobar")
>           local x,y,z -- regular locals
>
>           -- -----------------------------------------
>           -- all variables of type 'scope' are closed
>           -- -----------------------------------------
>         end

function scope(body)
    local list,res={}
    local function auto(close,msg)
        return function(t)
            if type(t)~='table' then error("need table: { expression }",2) end
            if t[1] then table.insert(list,{ arg=t[1], fn=close or io.close })
            else
                if msg=='weak' then return table.unpack(t,2) end
                error(msg or t[2] or "no resource",2)
            end
            return table.unpack(t)
        end
    end
    local ok,err=pcall(function() res={body(auto)} end)
    for i=#list,1,-1 do list[i].fn(list[i].arg) end
    if not ok then
        if type(err)~='string' then error(err,2)
        else error("scope error\nlua: "..err,2) end
    end
    return table.unpack(res)
end

scope(function(auto)
    local f=auto(io.close){ io.open "foobar" } -- will be closed
    local g,err=auto(io.close,"weak"){ io.open "foobar2" }
    local x,y,z -- regular locals
end)