Loop to include files

Here is my code:



local _dir = "../modules/"

for _files, _folders in SortedPairs( file.Find( _dir .. "*"  .. "/sv_*.lua", "LUA" ) ) do
	include( _files )
end


and my error:



[ERROR] lua/includes/extensions/table.lua:535: bad argument #1 to 'pairs' (table expected, got nil)
  1. pairs - [C]:-1
   2. SortedPairs - lua/includes/extensions/table.lua:535
    3. unknown - addons/sgn_darkrpmod/lua/autorun/include.lua:4


I’m really not sure what i’m doing wrong, does anyone have experience in looping to include files?

My file structure is addons/darkrp_addon/lua/autorun/include.lua
and… addons/darkrp_addon/lua/modules/module1/sv_module.lua

I’ve tried to look at the Dark RP code that includes the modules folders, but can’t seem to work it out :confused:

Include accepts a string but you’re passing the numerical key.

[editline]3rd June 2014[/editline]

Also, you’ve defined keyvalues wrong.
_files should be something like _filekey or something more accurate, while _folders should actually be _files. Shouldn’t matter much since they’re just arbitrary identifiers but it’ll temporarily confuse people looking through your code (including yourself)

Damn you’re right. So as I know there is only 1 should then do:



local _dir = "../modules/"

for _files, _folders in SortedPairs( file.Find( _dir .. "*"  .. "/sv_*.lua", "LUA" ) ) do
	include( _files[li] )
[/li]end


or (as seen in darkrp although I may have interpretit wrong.)



local _dir = "../modules/"

for _files, _folders in SortedPairs( file.Find( _dir .. "*"  .. "/sv_*.lua", "LUA" ) ) do
	for k, v in pairs( _files ) do
	        include( k )
        end
end



I thought file.Find returned two tables, files and folders?

No, no no

for k, v in pairs()

k typically represents the key while v represents the actual value. You can also assign any identifier you damn please to key, and value.

for example, likethis in pairs() do

Or

for 5InchElephantileKrakken, SubterraneanMoleBird in pairs()

Basically, changing the identifiers does not change what they represent. In the end, 5InchElephantileKrakken represents a table key, while SubterraneanMoleBird represents a value that the key is assigned to.

[editline]3rd June 2014[/editline]

And no, you only pass pairs() one table and the two values it returns are the numerical/string key first and the value it represents second.

[editline]3rd June 2014[/editline]

Oh, file find?

Here’s what you do:

local files, folders = file.Find(args and shit)

Then you do your k v in pairs(files) stuff

Ok, so doing file.Find( dir … “*” … "/sv*.lua", “LUA”) would return

_files[1] as there is only 1 sv_name.lua file in that folder? If that’s the case, how can I get the name of the file that is represented by _files[1]? Or am I getting this completely wrong

Here’s what I use when I am working on something:


local function AddCSDir( workingDir )

	local files, dirs = file.Find( workingDir .. "/*", "LUA" )

	for k, v in pairs( files ) do
		if not v:find("sv") and v ~= "init.lua" 
		and string.EndsWith( v, ".lua" ) then

			AddCSLuaFile( workingDir .. "/" .. v )
		end
	end

	for k, v in pairs( dirs ) do
		AddCSDir( workingDir .. "/" .. v )
	end
end



local function IsBaseFile( file )

	--Gotta love immediately crashing when trying to include 
	--a file within itself
	if file == "init.lua" or
	file == "cl_init.lua" or
	file == "shared.lua" then
		return true
	end

	return false
end

-- probably a bad idea to use this in any gamemode which will be distributed
-- but it sure makes development slightly easier
function IncludeDir( workingDir ) 

	--Use lsv because LUA didn't work on client
	local files, dirs = file.Find( workingDir .. "/*", "lsv" )

	if SERVER then

		for k, v in pairs( files ) do
			if not v:find("_cl") and not IsBaseFile(v) 
					and v:EndsWith(".lua") then

				include( workingDir .. "/" .. v )

			end
		end

	else

		for k, v in pairs( files ) do
			if not v:find("_sv") and not IsBaseFile(v)
					and v:EndsWith(".lua") then

				include( workingDir .. "/" .. v )

			end
		end

	end

	for k, v in pairs( dirs ) do
		IncludeDir( workingDir .. "/" .. v )
	end

end

It’s not super polished since I only use this for development, but it gets the job done. IIRC there’s also a similar function in cinema, if you want to check that out too.

Actually you were right the first time. It returns two tables, files and folders. But these tables need to be treated in different loops, you can’t just lump them together into one.

The name is the value in this case as the value returned is a string. Files in gmod are not modified or read using objects, rather they are interfaced with by looking up their names.

Here’s a skeleton: https://dl.dropboxusercontent.com/u/26074909/tutoring/_redistributable/basedev_gamemode.rar

This repeats code but gets the includes and recursion right plus it handles map directories correctly: https://dl.dropboxusercontent.com/u/26074909/tutoring/_redistributable/basedev_gamemode/gamemode/sh_init.lua

It demonstrates what BFG pointed out to you, regarding the two loops.

Now, if you want to build a loop which produces something like this: https://dl.dropboxusercontent.com/u/26074909/tutoring/file_structure/Client_Files.txt

Then you’d process the folders recursively building up, and using the complete length as the index; and simply add each file from the entire length to that particular key.

Simple function; it’ll be included in the base skeleton ( plus many others such as something to read the list into 1 file, generate addon files list, and addon info ) when I open it up the svn in the fileio class.