Page 1 of 1

Odd Require Path Problems

Posted: Thu May 25, 2017 7:07 am
by Drakkahn
For my current project I wanted to stop having to do a bunch of

Code: Select all

local package_name=require(package_path)
in my files so I decided to make my own file inclusion function. However, wonky things keep happening whenever I do the slightest changes. For example, just adding a comment to my lua_extend.lua file (file with funcs) when its working will cause it to literally no longer work. If someone could give me insight on how to solve this is would be highly appreciated.

lua_extend.lua

Code: Select all

function include(...)

	local args={...}
	for i,arg in ipairs(args) do

		--get the name of the package
		local name=arg
		for v=arg:len(),1,-1 do

			local c=arg:sub(v,v)

			if c=="/" or c==string.char(92) then

				name=arg:sub(v+1,arg:len())
				break

			end

		end

		if _G[name]==nil then 			--make sure not already included

			local v=require(arg)		--include file
			if _G[name]==nil then _G[name]=v end		--globalize table if not already so

		end

	end

end

function addRequirePath(path)

	package.path=package.path .. "./" .. path .. "/?.lua;"

end

Re: Odd Require Path Problems

Posted: Thu May 25, 2017 7:56 am
by 0x72
You missed a semicolon (this doesn't sound like lua, but it is :D). I bet this is somehow related, although your situation still seams weird.

Code: Select all

function addRequirePath(path)
  package.path=package.path .. ";./" .. path .. "/?.lua;"
end
Aside note: you can replace the inner loop in include with (But: why do we even need it? Can't we just pass exactly what's needed to include and skip this step?):

Code: Select all

local name = arg:gsub('.*[\\/]', '')

Re: Odd Require Path Problems

Posted: Thu May 25, 2017 2:26 pm
by raidho36
First of all you shouldn't autoinclude anything. Because this way you're guaranteed to mess something up because something automatically loaded when you didn't want it, or something didn't load when you wrongly expected it to.

Second of all, you shouldn't globalize it. The require function already does the caching so there's no reason you'd possibly want to cache it on top of that, you can simply require your module again and it'll return already loaded module handle. That and polluting global namespace and having worse performance due to using globals at all.

Re: Odd Require Path Problems

Posted: Thu May 25, 2017 4:31 pm
by Beelz
Below is an excerpt from the game template I use... Keep in mind I didn't trim it down so you'd have to edit to suit, but here it is nonetheless. What happens is I pass a folder to dbug.enumFiles which selects based on lib boolean, sends to requireFiles, and pcall requires everything and returns as a table. Not sure if it helps, but this is what I do for quick loading. Probably not the best method, but works for me. ;)
Also for reference dbug.print's arguments are: msg(string), prefix(string), force(bool)

Code: Select all

local function getFileExtension(path)
    return path:match("^.+(%..+)$")
end

local function requireFiles(files, folder)
    local countPass = 0
    local tbl = {}

    for _, file in ipairs(files) do
        local reqPath = file:gsub('/', '.')
        local name = file:sub(#file-7, #file-4)

        if name == 'init' then name = file:sub(#folder+2, #file-9) end
        reqPath = reqPath:sub(1, #reqPath-4)

        local success, err = pcall(require, reqPath)
        dbug.print(string.format('"%s" from "%s"', name, file), success and '++' or '**')

        if success then tbl[name] = err
        else dbug.print('\t' .. err, '**', true)
        end
    end
    dbug.print()
    return tbl
end

function dbug.enumFiles(folder, file_list, lib) -- lib = true means only loads folders with init inside
    dbug.print(string.format('ENUM: %s (%s)', folder, lib and 'modules' or 'files'))
	local file_list = file_list or {}
    local lib = lib or false

    local items = lfs.getDirectoryItems(folder)
    for _, item in ipairs(items) do
        local file = folder .. '/' .. item

        if not lib and getFileExtension(file) == '.lua' and lfs.isFile(file) then    -- load file
            table.insert(file_list, file)

        elseif lfs.isDirectory(file) then
        	if lfs.isFile(file..'/init.lua') then -- load module
        		table.insert(file_list, file..'/init.lua')

            else                              -- recursive search
                dbug.enumFiles(string.format('%s/%s', folder, file), file_list, lib)
            end
        end
    end

    dbug.print(string.format('\t%s %s found...', #file_list, lib and 'modules' or 'files'))
    return requireFiles(file_list, folder)
end

Re: Odd Require Path Problems

Posted: Fri May 26, 2017 6:00 am
by Drakkahn
So modifying

Code: Select all

package.path=package.path .. "./" .. path .. "/?.lua;"
to

Code: Select all

package.path=package.path .. ";./" .. path .. "/?.lua;"
didn't fix the problem. But thanks a lot for all the suggestions, I'm just gonna do something else and not globalize everything. I forgot that globals were slower than locals.

Re: Odd Require Path Problems

Posted: Fri May 26, 2017 4:38 pm
by slime
love's require searcher for love.filesystem that it adds to package.loaders doesn't use package.path. You can use love.filesystem.setRequirePath instead.