How do "require" work in lua files?

Hi,

Not sure if this is a very newbie question or not…

Say I have file1.lua and in it I have local file2 = require(“file2”) then does file1.lua inherit all the required files that are called in file2.lua?

Thanks.

I haven’t used Corona in a while but my guess to your question is no… I mean you can give it a try though! Just make three files with code in them and try to call code in the other other file? Can’t recall the syntax but would it be something like 

file2.file3.function();

How this works is a common question, but the short answer to your question is no.

The longer answer is: don’t confuse the global variables - which become available to all code when a file is load using require() - with inheritance. It’s a global vs local variable thing.

Any variable defined without ‘local’ will be global. That means any code which is loaded can use that variable. This is a very bad thing, generally, because it is much more computationally expensive to locate the global variable in memory.

What you should be doing is localising all variables. This is quite a broad subject, but just to expend on your post above, if you also had a ‘file3.lua’ then any global variables would be available there, as well. But, try defining *all* Lua files like this:

local lib = {} local go = "GO: " lib.person = "elifares" function lib.doSomething() local thing = "something" print( go .. lib.person .. " did " .. thing ) end return lib

Load that code in your main.lua with:

local things = require("things") things.doSomething()

You will notice that you do not have access to any of the variables directly, without using ‘things.’, so no global access.

‘person’ and ‘doSomething()’ are properties on the ‘lib’ table - which becomes accessible as ‘things’ in the main.lua

‘go’ is local to the things.lus only and ‘thing’ is local only to the inside of the ‘doSomething()’ function.

The lesson is to make everything local and no matter where you want to use a bus file you require it and use it like any typical table.

Thanks horacebury I wold like to participate in this thread, as a newbie too I would like to code in different modules better than a 3,700 line module. The thing is I do not understand how the require works to and when I look here o Google find no good explanation/tutorial. I use composer. For example if I want to locate all my images or functions in a file how do I call/use in another module? I read your comment but I’m not clear yet. Thanks in advance.

@Horacebury’s explanation was pretty good. But perhaps more examples will help. I have a module called “utilities.lua”. I’ll post the contents of a typical version, but I’ll remove the actual code and just leave the function definitions for keeping it concise:

local json = require( "json" ) local socket = require("socket") local http = require("socket.http") local ltn12 = require("ltn12") M = {} -- define the module M.isSimulator = ("simulator" == system.getInfo("environment")) function M.print\_r( t ) end function M.testNetworkConnection() end function M.saveTable(t, filename) end function M.loadTable(filename) end function M.copyFileTo( filename, destination ) end function M.ignoreTouch(event) end function M.urlencode(str) end function M.urldecode( str ) end function M.makeTimeStamp(dateString) end function string:trim() end function string:split( inSplitPattern, outResults ) end return M

This is all in a file called “utility.lua”. Then everywhere I want to access these functions I just do:

local utility = require("utility")

at the top of the module where I need access to them. Then if I want to print a table later in the code I just do:

utility.print\_r( tableToPrint )

or if I want to URL encode a string:

local URL = utility.urlencode( someString )

If I want more functions I just add them to the M table in utility.lua.  Note some of the functions are not attached to the M table but the string table.  For string:split and string:trim, I’m adding those functions directly to the global string object as it makes sense to do so, but I could have added them to M (which then becomes “utility” since that’s what I required it as.

I don’t require utility as a global, but a local, which means I have to require it everywhere I want to use it. The more complex the project, the more important it is to modularize your code.

Rob

@Rob thanks my mind it’s a lil more clear right now, and how I call images, text fields, buttons, widgets if they are in a different module?

This is where things get complicated to explain because there are multiple ways to do things and they all are the right way depending on what you want to do. Since we don’t know your intent, it’s really hard to get more specific. 

For instance, a button has it’s own functions to do the work of the button and you may not need to pass in information like the label, color and location, so you may not need access to the button at all. Or maybe you just need a reference to the button so you can change the label or color after the fact, or maybe you want to have it more configurable where you pass in custom functions to execute when the button is interacted with.  It’s really hard to provide examples without knowing the intent.  But here is a simple example:

-- buttons.lua local M = {} M.leftButton = nil M.rightButton = nil function M.setupButtons()         M.leftButton = widget.newButton( { code to create button } )         M.rightButton = wiget.newButton( { code to create button } ) end

Then in the module where you want to setup the buttons:

local buttons = require("buttons") buttons.setupButtons()

Later, if you want to change the label on a button:

buttons.leftButton:setLabel( "New Label" )

Rob

@Rob

I really admire your professionalism, I have closely followed your work in the forum and from all forums I have participated in my life you are the best moderator. Thank you for being here, clearing child doubts, thank you for your ethics and professionalism in the way you answer, is not easy task to understand newbies minds. THANKS!

I haven’t used Corona in a while but my guess to your question is no… I mean you can give it a try though! Just make three files with code in them and try to call code in the other other file? Can’t recall the syntax but would it be something like 

file2.file3.function();

How this works is a common question, but the short answer to your question is no.

The longer answer is: don’t confuse the global variables - which become available to all code when a file is load using require() - with inheritance. It’s a global vs local variable thing.

Any variable defined without ‘local’ will be global. That means any code which is loaded can use that variable. This is a very bad thing, generally, because it is much more computationally expensive to locate the global variable in memory.

What you should be doing is localising all variables. This is quite a broad subject, but just to expend on your post above, if you also had a ‘file3.lua’ then any global variables would be available there, as well. But, try defining *all* Lua files like this:

local lib = {} local go = "GO: " lib.person = "elifares" function lib.doSomething() local thing = "something" print( go .. lib.person .. " did " .. thing ) end return lib

Load that code in your main.lua with:

local things = require("things") things.doSomething()

You will notice that you do not have access to any of the variables directly, without using ‘things.’, so no global access.

‘person’ and ‘doSomething()’ are properties on the ‘lib’ table - which becomes accessible as ‘things’ in the main.lua

‘go’ is local to the things.lus only and ‘thing’ is local only to the inside of the ‘doSomething()’ function.

The lesson is to make everything local and no matter where you want to use a bus file you require it and use it like any typical table.

Thanks horacebury I wold like to participate in this thread, as a newbie too I would like to code in different modules better than a 3,700 line module. The thing is I do not understand how the require works to and when I look here o Google find no good explanation/tutorial. I use composer. For example if I want to locate all my images or functions in a file how do I call/use in another module? I read your comment but I’m not clear yet. Thanks in advance.

@Horacebury’s explanation was pretty good. But perhaps more examples will help. I have a module called “utilities.lua”. I’ll post the contents of a typical version, but I’ll remove the actual code and just leave the function definitions for keeping it concise:

local json = require( "json" ) local socket = require("socket") local http = require("socket.http") local ltn12 = require("ltn12") M = {} -- define the module M.isSimulator = ("simulator" == system.getInfo("environment")) function M.print\_r( t ) end function M.testNetworkConnection() end function M.saveTable(t, filename) end function M.loadTable(filename) end function M.copyFileTo( filename, destination ) end function M.ignoreTouch(event) end function M.urlencode(str) end function M.urldecode( str ) end function M.makeTimeStamp(dateString) end function string:trim() end function string:split( inSplitPattern, outResults ) end return M

This is all in a file called “utility.lua”. Then everywhere I want to access these functions I just do:

local utility = require("utility")

at the top of the module where I need access to them. Then if I want to print a table later in the code I just do:

utility.print\_r( tableToPrint )

or if I want to URL encode a string:

local URL = utility.urlencode( someString )

If I want more functions I just add them to the M table in utility.lua.  Note some of the functions are not attached to the M table but the string table.  For string:split and string:trim, I’m adding those functions directly to the global string object as it makes sense to do so, but I could have added them to M (which then becomes “utility” since that’s what I required it as.

I don’t require utility as a global, but a local, which means I have to require it everywhere I want to use it. The more complex the project, the more important it is to modularize your code.

Rob

@Rob thanks my mind it’s a lil more clear right now, and how I call images, text fields, buttons, widgets if they are in a different module?

This is where things get complicated to explain because there are multiple ways to do things and they all are the right way depending on what you want to do. Since we don’t know your intent, it’s really hard to get more specific. 

For instance, a button has it’s own functions to do the work of the button and you may not need to pass in information like the label, color and location, so you may not need access to the button at all. Or maybe you just need a reference to the button so you can change the label or color after the fact, or maybe you want to have it more configurable where you pass in custom functions to execute when the button is interacted with.  It’s really hard to provide examples without knowing the intent.  But here is a simple example:

-- buttons.lua local M = {} M.leftButton = nil M.rightButton = nil function M.setupButtons()         M.leftButton = widget.newButton( { code to create button } )         M.rightButton = wiget.newButton( { code to create button } ) end

Then in the module where you want to setup the buttons:

local buttons = require("buttons") buttons.setupButtons()

Later, if you want to change the label on a button:

buttons.leftButton:setLabel( "New Label" )

Rob

@Rob

I really admire your professionalism, I have closely followed your work in the forum and from all forums I have participated in my life you are the best moderator. Thank you for being here, clearing child doubts, thank you for your ethics and professionalism in the way you answer, is not easy task to understand newbies minds. THANKS!