[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Another option for closing variables
- From: Sergey Kovalev <kovserg33@...>
- Date: Mon, 8 Jul 2019 17:14:02 +0300
сб, 6 июл. 2019 г. в 07:44, Coda Highland <chighland@gmail.com>:
>
>
>
> On Fri, Jul 5, 2019 at 6:15 PM Sergey Kovalev <kovserg33@gmail.com> wrote:
>>
>> сб, 6 июл. 2019 г. в 00:24, Coda Highland <chighland@gmail.com>:
>> You could follow rule: one enter one exit point. So you will no need
>> in return. Here return used to live then scope, like break in a loop.
>
> No, thank you. I really don't have any interest in going back to programming in Pascal. One enter is fine, but one exit is unnecessarily restrictive -- even loops have break statements, and that's multiple exits.
>
It's not a problem. It could be rewritten to use returns:
function for_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) end
error(msg or t[2] or "no resource",2)
end
return table.unpack(t)
end
end
local function defer(fn) auto(fn){true} end
local ok,err=pcall(function() res={body(auto,defer)} 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
if #res>0 then return res end
end
function test()
for t in for_scope,function(auto,defer) -- scope.begin
local f,err=auto(io.close,"weak") { io.open "test2.txt" }
print(f,err)
defer(function() print "defer" end)
return auto(){ io.open "readme.txt" }:read()
end do return table.unpack(t) end -- scope.end
end
print(test())
-- output:
-- nil test2.txt: No such file or directory
-- defer
-- readme