Require path

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
Davïd
Prole
Posts: 12
Joined: Sun Jan 29, 2017 4:12 pm

Require path

Post by Davïd »

Hello,

I have the following folder structure :

/classes
classes.lua
--/data
--/data.lua
--/components
--/components.lua
----/movement
----/movement.lua

you get the idea. And I wonder if there is a way to require file like this

require('classes.components.movement')

instead of :

require('classes.components.movement.movement')

Thanks for enlightements
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Require path

Post by grump »

Sure, by moving movement.lua one level up into the components folder.
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Require path

Post by davisdude »

Without messing with the structure, as grum suggested, you have a couple of options available:
  • You can also put a file title "init.lua" inside of each directory, such as movement, which looks something like this:

    Code: Select all

    -- classes/components/movement/init.lua
    -- Match the parent directory
    local path = (...):match( '(.-)[^%./]+$' )
    return path .. 'movement.lua'
    
    Then you could require the directory itself, which would require the specific file:

    Code: Select all

    -- main.lua
    require 'classes.components.movement'
    
    Though this is a bit of a hassle, since you need to create a new file for each class that you make.
  • Alternatively, you could try messing with the package.path variable, though it could have some hard-to-find consequences later on if you're not careful with naming your files:

    Code: Select all

    -- main.lua
    package.path = './classes/components/?/?.lua;' .. package.path
    require 'movement' 
    
  • If you really wanted to achieve the exact structure you described without creating a custom file for each directory you could mokeypatch, or overwrite the require function, which I would strongly advise against and is typically not recommended (though still doable if you're desperate enough):

    Code: Select all

    -- Wrap everything in a do-block to reduce pollution to the local scope
    do
    	-- Store the old require to be used later
    	local _require = require
    	
    	-- Store the items in the directory, to check if one of the names matches
    	local directory = 'classes/components/'
    	local fileNames = love.filesystem.getDirectoryItems( directory )
    	
    	-- Overwrite require globally
    	function require( path )
    		-- Check to see if the last part of the path matches one of the fileNames
    		-- Get the last part of the path
    		local fileName = path:match( '^.-([^%./]+)$' )
    		for _, name in ipairs( fileNames ) do
    			-- File matches; use special format
    			if fileName == name then
    				return _require( directory .. fileName .. '.' .. fileName )
    			end
    		end
    		
    		-- File does not match; use regular require
    		return _require( pathname )
    	end
    end
    
    require 'classes.components.movement'
    
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
Davïd
Prole
Posts: 12
Joined: Sun Jan 29, 2017 4:12 pm

Re: Require path

Post by Davïd »

Thanks for answers. I changed structure like Grump suggested.

And I didn't know about init files. Thank you for such quality answer Davis.
Post Reply

Who is online

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