May
May

Reputation: 68

How do I change the deafult require search directory for Lua?

I know this is possible because I have changed it before. I changed it to a custom directory that Lua checks for modules/libraries.

If you don't know what I'm saying, here's what I'm saying: I want to be able to change the directories Lua checks to find the file I'm trying to require.

For some reason, whenever I run require it doesn't check the current directory for the file. I have tried googling how to do it and no answers. The time when I changed this was when I was talking to someone who programmed Love2D and he walked me through the steps, but that conversation is gone and I can't find it.

Any help is appreciated, just let me know! And if you have any questions don't forget to ask! Thanks!

Upvotes: 1

Views: 1216

Answers (2)

koyaanisqatsi
koyaanisqatsi

Reputation: 2823

My recommendation is to write a loader for path dependent require.
Because a script that modifies package.path and then loads another script that modifies also package.path ends up with a messy package.path.

A loader function in package.preload['name_of_loader_function'] returns in package.loaded
This is showing by a simple example...
( Shown in console: lua -i )

> package.preload['new_require']=function() return {'New to Lua?'} end
> newtab=require('new_require')
> table.concat(newtab)
New to Lua?
> table.concat(package.loaded.new_require)
New to Lua?

After that you can construct your loader with loadfile() and full path to your lua code.
But this time without extra () than it returns to package.loaded.

Lua 5.3.5  Copyright (C) 1994-2018 Lua.org, PUC-Rio
> package.preload['tprint']=loadfile('/tmp/tprint.lua')
> tprint=require('tprint')
> tprint(os)
Using pairs() for table print out
execute = function: 0x565d8a90
clock = function: 0x565d8b90
time = function: 0x565d8dc0
date = function: 0x565d8f60
remove = function: 0x565d8970
exit = function: 0x565d8a00
rename = function: 0x565d8910
difftime = function: 0x565d8b40
getenv = function: 0x565d89c0
setlocale = function: 0x565d88b0
tmpname = function: 0x565d8bd0

What was happen?

  1. require checks package.preload for a loader for 'tprint'
  2. require found and execute 'tprint' field function in package.preload
  3. package.preload.tprint returning its value to package.loaded.tprint
  4. require returns package.loaded.tprint to global tprint function
  5. tprint is ready for use and typed with table argument prints out table keys/values

This works only if no package.loaded.tprint exists.
Because require() looks first in package.loaded.tprint and if absent in package.preload.tprint.

Upvotes: 0

Piglet
Piglet

Reputation: 28994

You refer to the Lua 5.4 Reference Manual:

require

...

First require queries package.preload[modname]. If it has a value, this value (which must be a function) is the loader. Otherwise require searches for a Lua loader using the path stored in package.path. If that also fails, it searches for a C loader using the path stored in package.cpath. If that also fails, it tries an all-in-one loader (see package.searchers).

Let's click on package.path

A string with the path used by require to search for a Lua loader.

At start-up, Lua initializes this variable with the value of the environment variable LUA_PATH_5_4 or the environment variable LUA_PATH or with a default path defined in luaconf.h, if those environment variables are not defined. A ";;" in the value of the environment variable is replaced by the default path.

So either you that string at runtime as you would modify any other string.

Or you change the value of your system variable LUA_PATH_5_4 in case you want to change it system wide.

I think you can figure out the rest yourself.

Just print package.path and have a look at what's inside.

Upvotes: 2

Related Questions