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

Why Does Os.loadapi Copy The Functions Into A New Table After Loading Them?

Started by Pinkishu, 24 November 2013 - 09:44 AM
Pinkishu #1
Posted 24 November 2013 - 10:44 AM

local tAPIsLoading = {}
function os.loadAPI( _sPath )
local sName = fs.getName( _sPath )
if tAPIsLoading[sName] == true then
printError( "API "..sName.." is already being loaded" )
return false
end
tAPIsLoading[sName] = true

local tEnv = {}
setmetatable( tEnv, { __index = _G } )
local fnAPI, err = loadfile( _sPath )
if fnAPI then
setfenv( fnAPI, tEnv )
fnAPI()
else
printError( err )
		tAPIsLoading[sName] = nil
return false
end

local tAPI = {}
for k,v in pairs( tEnv ) do
tAPI[k] =  v
end

_G[sName] = tAPI
tAPIsLoading[sName] = nil
return true
end

as seen a tEnv is created, and the function that will create the functions of the API is placed into it, then run, now all the functions have been created in tEnv, now all the functions are copied over to another table, tAPI, then that is set to the _G key (which is the api name).
A bit of a weird thing to copy them over into another table, why was that done? The result is that any "global" variable create by the functions in the API will neither be in _G nor in the api table but in the fenv of the function

so if a function in the loaded API was

function foo()
  bar = "foo"
end

bar would neither be _G.bar nor in the _G,apitable.bar but getfenv(_G.apitable.foo).bar

(and why does this forum make my topic title weirdly capitalized..)
Edited on 24 November 2013 - 09:47 AM
ElvishJerricco #2
Posted 24 November 2013 - 10:55 AM
Although I'm not sure, I think it's done this way to enforce the convention of only using function calls for APIs, instead of setting and getting variables in the API table.
distantcam #3
Posted 24 November 2013 - 11:05 AM
Although I'm not sure, I think it's done this way to enforce the convention of only using function calls for APIs, instead of setting and getting variables in the API table.

Couldn't you then just add the tEnv to _G instead of copying tEnv to tAPI?
MKlegoman357 #4
Posted 24 November 2013 - 12:27 PM
I think it is being copied so that you couldn't call functions from global table thru your API:

test API

function test ()
  print("test")
end

test code

os.loadAPI("test")

test.test()
--> test

print(test.print)
--> nil

--// But if the table wouldn't be copied:

print(test.print)
--> function: 4cca9ed4    or something similar
Edited on 24 November 2013 - 11:32 AM
ardera #5
Posted 24 November 2013 - 12:58 PM
If I understood you right, it's because you could modify the environment of the API, and play with it.
MKlegoman357 #6
Posted 24 November 2013 - 01:09 PM
If I understood you right, it's because you could modify the environment of the API, and play with it.

If I understood myself correct, it's because only your functions or variables would be in your API and Global API _G wouldn't be copied inside your API.
ardera #7
Posted 24 November 2013 - 03:16 PM
If I understood you right, it's because you could modify the environment of the API, and play with it.

If I understood myself correct, it's because only your functions or variables would be in your API and Global API _G wouldn't be copied inside your API.

you could just set the metatable to {}
Edited on 24 November 2013 - 02:16 PM
theoriginalbit #8
Posted 24 November 2013 - 09:19 PM
(and why does this forum make my topic title weirdly capitalized..)
http://www.computercraft.info/forums2/index.php?/topic/15057-topic-titles-and-letter-case/
MKlegoman357 #9
Posted 25 November 2013 - 02:56 AM
you could just set the metatable to {}

If you would set environment to an empty table then your API couldn't use any of existing CC and Lua APIs.
Bomb Bloke #10
Posted 25 November 2013 - 03:31 AM
(and why does this forum make my topic title weirdly capitalized..)
http://www.computerc...nd-letter-case/
Dunno if there's any interest in changing it, but the setting in concern is "Stop shouting in topic titles" (which takes a rather heavy-handed approach to the task). Looks like it was enabled several months ago.
theoriginalbit #11
Posted 25 November 2013 - 03:32 AM
Dunno if there's any interest in changing it, but the setting in concern is "Stop shouting in topic titles" (which takes a rather heavy-handed approach to the task). Looks like it was enabled several months ago.
Very heavy handed, it should not change things that are not all uppercase. for example it should preserve things such as APIs or TheOriginalBIT or such, imo.
ardera #12
Posted 25 November 2013 - 07:47 AM
you could just set the metatable to {}

If you would set environment to an empty table then your API couldn't use any of existing CC and Lua APIs.
Oh, your right!