Posted 23 November 2012 - 11:48 AM
Hi, I've been thinking a lot about loading code.
I was not satisfied with os.loadAPI, because:
-it clutters the global namespace;
-by making a shallow copy of the API environment's, one is oblidged to store values that an user may edit in a table, like so (i don't use the 'code' box cause the letters are rather small) :
–api name: myapi
a=1 –attempts to edit this (e.g. myapi.a=2) will not have effect in the result of the following function:
function geta() return a end
t={1,2} – myapi[1]=8 will have an effect, but myapi={8,2} will not
function gett() return t end
vars={a=1,t={1,2}} –it's a workaround, but an awkward one
But still, there's this weird thing:
myapi._G.print==print
>>true
Using the loadreq API I wrote, I can easily run a file and get the return; an API written in that way would look like this:
–api name: myapi
M={}
M.a=1 –this is a public variable
function M.geta() print(M.a) end
local t={1,2} –private variable, no one can edit it
function M.gett() return t end
return M
———————-
–how to load it:
myapi=require '(path to myapi)'
myapi.a
>>1
myapi.t
>>nil
myapi._G
>>nil
Still, I have to prefix everything I want to share with something (this case, M).
So I decided to do this:
–api name: myapi
local print=print
env=getfenv()
setmetatable(env,nil) –before it was {__index=G}, just like os.loadAPI does
–no more global access
a=1 –this is a public variable
function geta() print(a) end –acess the local variable
local t={1,2} –private variable, no one can edit it
function gett() return t end
return env –locals aren't part of the environment
What do you use? Do you use anything?
I was not satisfied with os.loadAPI, because:
-it clutters the global namespace;
-by making a shallow copy of the API environment's, one is oblidged to store values that an user may edit in a table, like so (i don't use the 'code' box cause the letters are rather small) :
–api name: myapi
a=1 –attempts to edit this (e.g. myapi.a=2) will not have effect in the result of the following function:
function geta() return a end
t={1,2} – myapi[1]=8 will have an effect, but myapi={8,2} will not
function gett() return t end
vars={a=1,t={1,2}} –it's a workaround, but an awkward one
But still, there's this weird thing:
myapi._G.print==print
>>true
Using the loadreq API I wrote, I can easily run a file and get the return; an API written in that way would look like this:
–api name: myapi
M={}
M.a=1 –this is a public variable
function M.geta() print(M.a) end
local t={1,2} –private variable, no one can edit it
function M.gett() return t end
return M
———————-
–how to load it:
myapi=require '(path to myapi)'
myapi.a
>>1
myapi.t
>>nil
myapi._G
>>nil
Still, I have to prefix everything I want to share with something (this case, M).
So I decided to do this:
–api name: myapi
local print=print
env=getfenv()
setmetatable(env,nil) –before it was {__index=G}, just like os.loadAPI does
–no more global access
a=1 –this is a public variable
function geta() print(a) end –acess the local variable
local t={1,2} –private variable, no one can edit it
function gett() return t end
return env –locals aren't part of the environment
What do you use? Do you use anything?