Page 1 of 1

[closed]Are functions global

PostPosted: Fri Feb 22, 2013 17:55
by webdesigner97
Hi community,
I just wondered wheter a function defined in Mod X can be accessed from Mod Y...

Here's what I mean:

Mod X
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
function testfunc()
 print("Hello World")
end

Mod Y:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
testfunc()

PostPosted: Fri Feb 22, 2013 17:58
by Traxie21
Yes. It is in this format:

ModX:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
function testfunc()
 print("Hello World")
end


ModY:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
ModX.testfunc()

PostPosted: Fri Feb 22, 2013 18:03
by webdesigner97
Traxie21 wrote:Yes. It is in this format:

ModX:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
function testfunc()
 print("Hello World")
end


ModY:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
ModX.testfunc()

Wow, that's very good. This would add some more stuff to my PHP-Server-Manager. It would automatically install a mod which provides some functions to interact with my Server-Manager, such as notifications :D

THX

PostPosted: Fri Feb 22, 2013 18:03
by PilzAdam
Traxie21 wrote:Yes. It is in this format:

ModX:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
function testfunc()
 print("Hello World")
end


ModY:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
ModX.testfunc()

Wrong. The version in the first post is correct. All mods run in the same Lua environment, so they share a global namespace. One cant access functions/variables that are local, tough.

PostPosted: Fri Feb 22, 2013 18:12
by VanessaE
PilzAdam wrote:Wrong. The version in the first post is correct. All mods run in the same Lua environment, so they share a global namespace. One cant access functions/variables that are local, tough.

...which means, in turn, that when you declare a function in your mod, either you need to make it local, or you need to give it a very unique name, or do what I do and force it into a new namespace (e.g. plantslib:spawn_on_surfaces()).

That way, your function names don't conflict with anyone else's mods.

PostPosted: Fri Feb 22, 2013 18:18
by webdesigner97
Uhm, now I'm confused... Which is the right way to access this "external" function?

PostPosted: Fri Feb 22, 2013 18:27
by PilzAdam
webdesigner97 wrote:Uhm, now I'm confused... Which is the right way to access this "external" function?

The right way is simply call the function (as in the first post).
But its recommended to give the function a unique name, so that you dont conflict with other mods.
E.g. put all mods into one table:
ModA
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
modA = {}

function modA.myEpicFunction()
    print("Works")
end

ModB:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
modA.myEpicFunction()

But again, this is only a recommendation.

PostPosted: Fri Feb 22, 2013 18:35
by webdesigner97
PilzAdam wrote:
webdesigner97 wrote:Uhm, now I'm confused... Which is the right way to access this "external" function?

The right way is simply call the function (as in the first post).
But its recommended to give the function a unique name, so that you dont conflict with other mods.
E.g. put all mods into one table:
ModA
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
modA = {}

function modA.myEpicFunction()
    print("Works")
end

ModB:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
modA.myEpicFunction()

But again, this is only a recommendation.


Ok, now I understood :) Thank you very much!

PostPosted: Fri Feb 22, 2013 18:39
by VanessaE
If you declare a function in mod A, mod B can access that function by just calling it by name. So if in mod A you declare a function with a name like "printvars", mod B can just call it directly with no special preparations, e.g. printvars(foo, bar, blah, ...)

What you should do is declare it in a new namespace, e.g.

mymod:printvars = function(foo, bar, blah, ...)

and then call it with that name. Failing that, you could use underscores and just give it a descriptive name that's least likely to be confused with some other mod, e.g. mymod_print_vars_to_screen or something.

The bottom line is that you must always make sure your functions have unique, hard-to-conflict-with names if they aren't local.

PostPosted: Fri Feb 22, 2013 18:42
by webdesigner97
ok. But I never worked with namespaces before. how do I declare them?

PostPosted: Fri Feb 22, 2013 18:56
by VanessaE
ok. But I never worked with namespaces before. how do I declare them?


Just like I wrote. In mod A, where you want the actual working code for your function to reside, you'd do this:

mymod:printvars = function(foo, bar, blah, ...)
...some code here...
...some code here...
...some code here...
end

and then just call mymod:printvars(foo, bar, blah) in your other mods. Obviously, the parameter names and how many you use are up to you. For a working example, look at my plantlife/plants_lib mod.

PostPosted: Fri Feb 22, 2013 18:59
by PilzAdam
I suggest to simply dont listen to VanessaE here, because she just makes things too complicated. The : is used in Lua for object oriented programming, but you really dont need it here.

PostPosted: Fri Feb 22, 2013 21:47
by prestidigitator
That seems a little harsh, but I agree that the colon isn't necessary here because you are expecting other modules to use your global variable to call the functions, rather than passing a reference different objects around. So you really don't need a reference to your object implicitly passed to each function call.

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
-- Completely equivalent:

function object:func(a, b, c, ...)
   -- do stuff
end

object.func = function(self, a, b, c, ...)
   -- do stuff
end

-- Also completely equivalent:
object:func(x, y, z)
object.func(object, x, y, z)


What we are talking about is the difference shown by this example, using the default API:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
-- Yes, "minetest" is an object.  However, since we always use the same object to make these calls,
--    we don't need to pass a reference to it around:
local playerlist = minecraft.get_connected_players()
local status = minecraft.get_server_status()
local inv = minecraft.get_inventory({ type = "player", name = "myname"})

-- However, "inv" here points to some inventory (InvRef) object, and when we call
--    a method on that object the method HAS to know WHICH inventory it is dealing with!
local empty = inv:is_empty()


So what you are talking about is probably the first case where you simply call "mymodule.myfunction(...)".

On the other hand, if you want a function that is ONLY callable within the same file (NOTE: not the entire module, but the same actual *.lua FILE!), you want:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local my_func = function(a, b, c)
   -- do stuff
end

my_func(x, y, z)


Which keeps it from conflicting with any other module that might use a function, variable, or object called "my_func".

PostPosted: Sat Feb 23, 2013 14:24
by Traxie21
Gaah. It would've been easier If I didn't copy-paste that first post. Forgot to edit the ModX part. Yes, I do know how it is supposed to work.

PostPosted: Sun Feb 24, 2013 10:55
by webdesigner97
Thx @ all for your help! I'll try it out!