Codea - global var, module and encapsulation

Hello !

For people who love make real clean module without globals and used it in Codea, this is (I think) the best way :
=> Use require function

For use it in Codea, we need to add (or set in this case) package.path with the good path, this is an example of how this work :

MyModule

-- MyModule

local MyModule = class() -- or {}

function MyModule:init(...)
  -- ...
end

-- private function
local function doSomething_aux(...)
  -- ...
end

function MyModule:doSomething(...)
  doSomething_aux(arg)
  -- ...
end

return MyModule

Main

-- Main

PROJECTNAME = "" -- the name or your current Codea project
package.path = os.getenv("HOME") .. "/Documents/" .. PROJECTNAME .. ".codea/?.lua"

local MyModule = require "MyModule"

function setup()
  myModule = MyModule()
  myModule:doSomething()
end

And if you need other projects, you need to add the path in package.path like :

DEPENDENCIES = {
  "MyOtherCodeaProject1",
  "MyOtherCodeaProject2"
}

for _,dependency in ipairs(DEPENDENCIES) do
  package.path = package.path .. ";" .. os.getenv("HOME") .. "/Documents/" .. dependency .. ".codea/?.lua"
end

Or you can overwrite a new required function like this :


-- required
-- - project : string : name of project in Codea you want
--                  or nil : auto replaced by PROJECTNAME
-- - files : string : return just this module in project
--             or table : return a table who contain all required modules
--             or nil : return all modules of the project
-- PS: change the package.path temporarily
__required = required
function required(project, files)
  local path = package.path
  project = project or PROJECTNAME
  package.path = os.getenv("HOME") .. "/Documents/" .. project .. ".codea/?.lua"
  if files == nil or type(files) == "table" then
    local tbl = {}
    for _,file in ipairs(files or listProjectTabs(project)) do
      tbl[#tbl+1] = __required(file)
    end
    package.path = path
    return tbl
  elseif type(files) == "string" then
   local request = __required(files)
   package.path = path
   return request
  end
end

I think this can be useful for library or tools (and other projects !) because there isn’t problems with use of same module name.

Have a nice day !

$Edit - Thanks @Jmv38 for found typo error !

@hyrovitalyprotago very intersting.
I have a couple questions: do you confirm:

  • the return myModule instead of return MyModule (typo?).
  • package.path = package.path .. os.getenv("HOME") .. "/Documents/" .. dependency .. ".codea/?.lua" without separators between paths?
  • i guess in last bloc this package.path .. os.getenv("HOME") .. "/Documents/" .. project .. ".codea/?.lua" is a typo? (no affectation, you meant package.path = os.getenv("HOME") etc ? )

@Jmv38 - Thanks ! Yes, a lot of typo because I have write this too quickly… Sorry :wink: