Jump to content




Inherited Key Include


  • You cannot reply to this topic
5 replies to this topic

#1 oeed

    Oversimplifier

  • Members
  • 2,095 posts
  • LocationAuckland, New Zealand

Posted 15 March 2013 - 10:05 AM

Essentially what I am trying to do is make a custom include function so that if I include the file 'One' and that contains an include to file 'Two', Two becomes One.Two

For example:

Startup or whatever
include("One")
print(One.Two) --should be Testing123

One
include("Two")

Two
return "Testing123"

So essentially rather than two being _G.Two I would like it to be _G.One.Two

The way I've been trying to do it doesn't really work. Anyone have a suggestion on how to do this?

#2 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 15 March 2013 - 10:14 AM

Try customizing os.loadAPI. It nearly has the functionality you're looking for. getfenv() maaay be able to get you the rest of the way there.

#3 oeed

    Oversimplifier

  • Members
  • 2,095 posts
  • LocationAuckland, New Zealand

Posted 15 March 2013 - 10:21 AM

View PostLyqyd, on 15 March 2013 - 10:14 AM, said:

Try customizing os.loadAPI. It nearly has the functionality you're looking for. getfenv() maaay be able to get you the rest of the way there.

That's what I've tried. It's setting the key for _G[...] = tAPI that I can't get.

Here's the (rather messy) code I have at the moment:
function include(_sPath)
-- the os.loadAPI slightly modified
local sName = fs.getName( _sPath )
 
local tEnv = {
  include = include
}
setmetatable( tEnv, { __index = _G } )
local fnAPI, err = loadfile( _sPath )
if fnAPI then
  setfenv( fnAPI, tEnv )
  includeStack[#includeStack + 1] = sName
  print(#includeStack)
  fnAPI()
else
  error("Failed to include '"..sName.."'. "..err)
  return false
end

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

--[[
--another failed attempt
local tTbl = _G
for _,v in ipairs( includeStack ) do
  if tTbl == nil then
   tTbl = {}
  end
  tTbl = tTbl[v]
end]]--

kStr = "_G"
for _,v in ipairs( includeStack ) do
  kStr = kStr.."."..v
  print(kStr)
end
tTbl = loadstring(kStr)
	    --this should just be replacing the load string, how do i set the key?
tTbl = tAPI
includeStack[#includeStack] = nil
return true
end


#4 GopherAtl

  • Members
  • 888 posts

Posted 15 March 2013 - 10:39 AM

some fiddling, using loadAPI as a base, came up with this, which seemed to work

local isIncluding = {}
local includeContext={_G}
function include(_sPath)
  local sName = fs.getName( _sPath )
  if isIncluding[sName] == true then
    printError( "circular inclusion detected!" )
    return false
  end
  isIncluding[sName] = true
  local tAPI = {}
   
  local myEnv=getfenv(1)
  local tEnv = {}
  setmetatable( tEnv, { __index = _G } )
  local fnAPI, err = loadfile( _sPath )
  if fnAPI then
    setfenv( fnAPI, tEnv )
    includeContext[#includeContext+1]=tAPI
    fnAPI()
    table.remove(includeContext)
  else
    printError( err )
    isIncluding[sName] = nil
    return false
  end
 
  for k,v in pairs( tEnv ) do
    tAPI[k] =  v
  end
 
  includeContext[#includeContext][sName] = tAPI 
  isIncluding[sName] = nil
  return true
end

The test code I used:
Spoiler


#5 oeed

    Oversimplifier

  • Members
  • 2,095 posts
  • LocationAuckland, New Zealand

Posted 15 March 2013 - 11:03 AM

View PostGopherAtl, on 15 March 2013 - 10:39 AM, said:

some fiddling, using loadAPI as a base, came up with this, which seemed to work

local isIncluding = {}
local includeContext={_G}
function include(_sPath)
  local sName = fs.getName( _sPath )
  if isIncluding[sName] == true then
	printError( "circular inclusion detected!" )
	return false
  end
  isIncluding[sName] = true
  local tAPI = {}
  
  local myEnv=getfenv(1)
  local tEnv = {}
  setmetatable( tEnv, { __index = _G } )
  local fnAPI, err = loadfile( _sPath )
  if fnAPI then
	setfenv( fnAPI, tEnv )
	includeContext[#includeContext+1]=tAPI
	fnAPI()
	table.remove(includeContext)
  else
	printError( err )
	isIncluding[sName] = nil
	return false
  end

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

  includeContext[#includeContext][sName] = tAPI
  isIncluding[sName] = nil
  return true
end

The test code I used:
Spoiler

Cheers, this looks good. I'll try it out soon.

#6 GopherAtl

  • Members
  • 888 posts

Posted 15 March 2013 - 11:09 AM

just noticed I forgot to remove that "myEnv=getfenv(1)" line. It is meaningless and should be snipped.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users