This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
CoolisTheName007's profile picture

Loading code - APIS versus Lua 5.1 modules

Started by CoolisTheName007, 23 November 2012 - 10:48 AM
CoolisTheName007 #1
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?
kazagistar #2
Posted 23 November 2012 - 11:58 PM
I have played around with a few models but my favorite by far is just calling the library with dofile, and having my libraries store all their functions and such in tables.

While in theory namespace conflicts can be an issue, in practice, it is rarely a problem, and I keep the global namespace of the calling function nice and clean for the most part, but I can modify it however I want easily from within a library, load multiple tables, intentionally overwrite part or all of another api, etc.
CoolisTheName007 #3
Posted 24 November 2012 - 04:24 AM
snip

EDIT: I wrote an entire post before noticing you use dofile (still keeps the problem of having to store everything in tables) ; oh, well:

Even if this isn't real life programming, I've noticed that people have already come a long way, e.g. red_works GUI platform, LiquydNet, ect.
If I manage to start repacking content in a more independent way, e.g. keeping the code local and not messing with _G, it will be easier for ComputerCrafters to use the already awesome programs people already did.