Include - A lightweight dynamic tab and project loader

Following on a little bit from experimenting with reflecting class names I’ve been playing around on and off with a function which will import a tab from another Codea project without using a dependency or requiring code to be commented out.

I was inspired after stumbling across setfenv() in the lua spec and having a look through cmodule by @toadkick
which is a very capable and elegantly written dynamic loader :slight_smile:

Include is a bit smaller and has a narrower scope. It is just 102 lines and exposes only four main global functions include,xinclude, import and ximport all of which will load global objects / classes from a list of project tabs, projects or any combination thereof into an isolated environment where each tab is cached and then its members exported to a table for use with a local or directly to the _G table. Each function has a significant but subtle difference between its counterparts.

include - loads the requested projects / tabs into isolated environment and then returns exports in two return values a unified shallow copy table of all items from the list of includes/imports and a name-spaced shallow copy table by project name for all includes/imports.

local all,ns = include("ProjectName","OtherProjectName:TabName")

local c = all.ClassName()

local nc = ns.ProjectName.ClassName()

Note: the unified table will replace two globals named identically on a last write wins basis even if they are in separate projects. The name-spaced table will not because everything is arranged into ProjectName.classname accessors.

xinclude - returns the name-spaced table of requested project tabs from include.

local ns = xinclude("ProjectName","OtherProjectName:TabName")

local p = ns.ProjectName.ClassName()

local o = ns.OtherProjectName.ClassName()

import - imports the unified table of objects from include into the _G table

import("ProjectName","OtherProjectName:TabName")

local cg = ClassName()

ximport - imports the namespace table of objects from include into the _G table

ximport("ProjectName","OtherProjectName:TabName")

local pcg = ProjectName.ClassName()
local ocg = OtherProjectName.ClassName()

Source Code: https://gist.github.com/XanDDemoX/5989154

Edit: Updated v1.01: Fixed typo in ximport function.

Very cool! Thanks, This will come in handy.

I keep getting include() and import() nil errors. Library is linked

Sorry, stupid mistake. Had all the code in the main tab and nothing is the imported tab.

I’m really liking this. So what would be the best way to include/import 2 tabs from a project that has 4 tabs?

Do you know of toadkick’s cmodule code? It might be worth your looking at. (I think there are links on the wiki.)

I do @Andrew_Stacey its very impressive and was part of my inspiration for this :slight_smile: but this does things a little differently :wink:

Thanks @Briarfox :slight_smile: To include two tabs from a project simply do :

-- access classes etc from a local

local tabs  = include("ProjectName:Tab1","ProjectName:Tab2")

-- or for global access import into _G 

import("ProjectName:Tab1","ProjectName:Tab2")