Odd Require Path Problems

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Drakkahn
Prole
Posts: 28
Joined: Sat Jan 17, 2015 11:09 pm

Odd Require Path Problems

Post 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
User avatar
0x72
Citizen
Posts: 55
Joined: Thu Jun 18, 2015 9:02 am

Re: Odd Require Path Problems

Post 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('.*[\\/]', '')
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Odd Require Path Problems

Post 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.
User avatar
Beelz
Party member
Posts: 234
Joined: Thu Sep 24, 2015 1:05 pm
Location: New York, USA
Contact:

Re: Odd Require Path Problems

Post 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

Code: Select all

if self:hasBeer() then self:drink()
else self:getBeer() end
GitHub -- Website
User avatar
Drakkahn
Prole
Posts: 28
Joined: Sat Jan 17, 2015 11:09 pm

Re: Odd Require Path Problems

Post 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.
User avatar
slime
Solid Snayke
Posts: 3131
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Odd Require Path Problems

Post 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.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 45 guests