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

API's table name with dot

Started by ZethMatthews, 13 March 2015 - 04:17 PM
ZethMatthews #1
Posted 13 March 2015 - 05:17 PM
Hey, all.

I have an API in a file named "zUtils.api". I have included file extensions on almost everything I've written just so I can more easily recognize what it is. However, when I use os.loadAPI("zUtils.api") to load the API, I can't seem to call anything in it without getting an "Attempted to index nil" error:

zUtils.api.listPeripherals();

I get that this is from the dot in the name and I could simply rename the API file to "zUtils", but I'd like to keep the extension. Is there a way to force a name on the loaded API table? (or reference the one that should have been made by the above?)

Notes:
zUtils = nil
zUtils_api = nil
zUtilsapi = nil
zUtils.api (results in error)
os.loadAPI returned true, so I know it was loaded.
Lyqyd #2
Posted 13 March 2015 - 06:50 PM
You can access it via _G["zUtils.api"].listPeripherals(). Or you can rename the file.
GopherAtl #3
Posted 13 March 2015 - 07:08 PM
Not certain if it would work, but within the api, you may be able to define a table _G["zUtils"] and put all your functions in it, like this


  --at the top
  _G["zUtils"] = {}

  --functions or accessible constants become
  zUtils.someConstant=42

  function zUtils.myFunc()
	--do stuff
  end

Not positive this works, and not in a position to test at the moment, but it may? Worth a shot anyway.

Depending on what you're doing exactly, you might just consider making your own version of os,loadAPI, instead. There's no java-side magic to it, it's a plain old lua function defined in bios.lua, in your jar file. Your own version could discard the .api part automatically, and use the base name only.
Edited on 13 March 2015 - 06:09 PM
MKlegoman357 #4
Posted 13 March 2015 - 07:29 PM
Another very simple solution could be to just rename (add an 'alias') the API:


_G.zUtils = _G["zUtils.api"]
Edited on 13 March 2015 - 06:29 PM
ElvishJerricco #5
Posted 13 March 2015 - 07:36 PM
I like to override os.loadAPI on most of my computers to I can keep myself sane. The big thing is that I can let it strip file extensions, but I also use it to have os.loadAPI load the file with os.run, so that my os.run overrides work on APIs. Really, I should make some kind of OS layer for this stuff, but meh.


local tAPIsLoading = {}
function os.loadAPI(path)
    if type(path) ~= "string" then
        error("Expected string", 2)
    end

    local sName = fs.getName(path):gsub("%.%w+$", "")

    if tAPIsLoading[sName] == true then
        printError( "API "..sName.." is already being loaded" )
        return false
    end
    tAPIsLoading[sName] = true

    local tEnv = {}
    if not os.run(tEnv, path) then
        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
Lupus590 #6
Posted 13 March 2015 - 08:06 PM
I like to override os.loadAPI on most of my computers to I can keep myself sane. The big thing is that I can let it strip file extensions, but I also use it to have os.loadAPI load the file with os.run, so that my os.run overrides work on APIs. Really, I should make some kind of OS layer for this stuff, but meh.


-snip-    

Mind if I use this? I plan on making an OS and like using file extensions too.
ElvishJerricco #7
Posted 13 March 2015 - 08:17 PM
I like to override os.loadAPI on most of my computers to I can keep myself sane. The big thing is that I can let it strip file extensions, but I also use it to have os.loadAPI load the file with os.run, so that my os.run overrides work on APIs. Really, I should make some kind of OS layer for this stuff, but meh.


-snip-	

Mind if I use this? I plan on making an OS and like using file extensions too.

No problem.