How to get undeclared global variable warning on interface?

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

How to get undeclared global variable warning on interface?

by Wuzzy » Sun May 24, 2015 15:36

Hi!
In a previous version of Minetest, Minetest showed a warning directly on the interface when an undeclared global variable has been accessed.
But now, this feature got removed again and it is only written in debug.txt.

Personally, I find this warning one of the most useful warnings of Minetest, because accessing undeclared global variables is not only bad practice, but a likely cause of bugs. Just today I have squashed another bug with the help of these warnings.
IMO a good Lua script should avoid this completely.

First question: How do I get the undeclared global variable warning on interface?

Second question: Why is it not shown in the interface by default anymore? I know, many mods use this kind of bad practise, so you'll get many such warnings, but it is unintentionally most of the time and it is very easy to forget a “local” and (seemingly) get away with it.
Screaming it right into the interface would force mod makers to fix this kind of bad practice. Also, because mod users would quickly start to complain. But maybe there is a better rationale to remove it from the interface anyways?

But I certainly want Minetest to scream loudly and proudly this warning to the interface, at least in my Minetest installation.

Here are some examples of the warning messages I am talking about:

16:29:15: WARNING: Undeclared global variable "pos" accessed at ...test/games/hungry_games/mods/hungry_games/engine.lua:27
16:30:57: WARNING: Assignment to undeclared global "obj" inside a function at ...test/games/hungry_games/mods/hungry_games/engine.lua:36.
16:30:57: WARNING: Assignment to undeclared global "winnerPos" inside a function at ...test/games/hungry_games/mods/hungry_games/engine.lua:107.
16:30:57: WARNING: Assignment to undeclared global "winnerName" inside a function at ...test/games/hungry_games/mods/hungry_games/engine.lua:108.


Most of these bugs are fixed by simply writing “local” in front of the name. Or you make an explicit global assignment to the variable beforehand, if it was that you wanted to do.
 

User avatar
rubenwardy
Member
 
Posts: 4500
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

Re: How to get undeclared global variable warning on interfa

by rubenwardy » Sun May 24, 2015 18:50

It's confusing for new players.

https://github.com/minetest/minetest/bl ... ua#L51-L52

Change

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
warn(("Undeclared global variable %q accessed at %s:%s")
            :format(name, info.short_src, info.currentline))


to

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
minetest.log("error", ("Undeclared global variable %q accessed at %s:%s")
            :format(name, info.short_src, info.currentline))
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Re: How to get undeclared global variable warning on interfa

by Wuzzy » Sun May 24, 2015 19:29

It's confusing for new players.

True, but the warning really should not be there in the first place. The modder is to blame. ;-)
Anyways, it's not that important.

But thanks for you help. :-)
 

prestidigitator
Member
 
Posts: 632
Joined: Thu Feb 21, 2013 23:54

Re: How to get undeclared global variable warning on interfa

by prestidigitator » Sun May 24, 2015 20:11

There's one case where I don't like the warning. Sometimes when creating a namespace you don't want to depend on the order of execution. So you might write this in two or more different places:

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
namespace = namespace or {};

namespace.var = ...;
function namespace.func() ... end;


I'd be nice to differentiate a simple check for nil like this and true dependence on value, but there's really no such (simple, built-in) mechanism in Lua. You'd have to iterate through all the keys of the table or create a secondary table with a dedicated API for presence testing or something like that. Maybe:

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
namespace = existing_or_empty_global_table("namespace");


...which is quite ugly (though admittedly clear in its meaning).
 

TeTpaAka
Member
 
Posts: 131
Joined: Sat Dec 28, 2013 21:54

Re: How to get undeclared global variable warning on interfa

by TeTpaAka » Sun May 24, 2015 20:32

prestidigitator wrote:There's one case where I don't like the warning. Sometimes when creating a namespace you don't want to depend on the order of execution. So you might write this in two or more different places:

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
namespace = namespace or {};

namespace.var = ...;
function namespace.func() ... end;


I'd be nice to differentiate a simple check for nil like this and true dependence on value, but there's really no such (simple, built-in) mechanism in Lua. You'd have to iterate through all the keys of the table or create a secondary table with a dedicated API for presence testing or something like that. Maybe:

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
namespace = existing_or_empty_global_table("namespace");


...which is quite ugly (though admittedly clear in its meaning).


There seems to be a way, I think. Intllib used to do it this way:
https://github.com/kaeza/minetest-intllib/commit/2ef1abad55f0e1b8b76169cdb1da3bc3f8749c67#diff-d7d74284e2e39f6c06d199c8e2bedbd0R2
 

prestidigitator
Member
 
Posts: 632
Joined: Thu Feb 21, 2013 23:54

Re: How to get undeclared global variable warning on interfa

by prestidigitator » Sun May 24, 2015 21:32


Hmm. It's a way of getting around the warning, true, but it's also perhaps a little subversive to use rawget() or rawset(). For example, if metatables were used for additional functionality using an always empty global table (e.g. to detect when certain variables are changed as well as initially set), using rawget() might always return nil. To be fair I suppose such a mechanism could replace the rawget() and/or rawset() functions too, but outside a security mechanism there's often a limit to the amount of paranoia you want to apply.
 

User avatar
rubenwardy
Member
 
Posts: 4500
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

Re: How to get undeclared global variable warning on interfa

by rubenwardy » Sun May 24, 2015 21:38

See minetest.global_exists()

Wuzzy wrote:
It's confusing for new players.

True, but the warning really should not be there in the first place. The modder is to blame. ;-)
Anyways, it's not that important.

But thanks for you help. :-)


You can't rely on maintainers to go through all their mods and correct this. It would be nice to have a mod debug mode. The craft recipe checker could be included too. Although mod developers could just not know about such a mode.

If there were no existing mods, it would be fine to put it on the interface. Except maybe that libraries such as Lua socket trigger the warnings.



As an additional note, I much prefer if foobar then to if minetest.global_exists("foobar") then
 

prestidigitator
Member
 
Posts: 632
Joined: Thu Feb 21, 2013 23:54

Re: How to get undeclared global variable warning on interfa

by prestidigitator » Sun May 24, 2015 22:21

rubenwardy wrote:See minetest.global_exists()

Cool. Added to dev wiki.
 

christoferlevich
Member
 
Posts: 55
Joined: Thu Dec 01, 2016 23:44

Re: How to get undeclared global variable warning on interfa

by christoferlevich » Sat Dec 10, 2016 12:05

Wuzzy wrote:Most of these bugs are fixed by simply writing “local” in front of the name.


Please forgive me if this question sounds ignorant, I am very new to the game, but are you saying if I simply add the word 'local' to the file it solves the error? I would like to minimize errors regardless of their impact on the game. I am using it in a school district, and I want to get the students involved in the game and the coding (as we go).
 

User avatar
Wuzzy
Member
 
Posts: 2161
Joined: Mon Sep 24, 2012 15:01
GitHub: Wuzzy2
IRC: Wuzzy
In-game: Wuzzy

Re: How to get undeclared global variable warning on interfa

by Wuzzy » Sat Dec 10, 2016 12:32

No, the word “local” must be written in front of the variable name, not in front of the file name.

I think it would be best if you beef up your Lua knowledge first and learn about scope, local variables and global variables. :P

The general Minetest recommendation is to only use variables by default and only use them if you REALLY need them. And if you use them, use them with care. Because all mods have to share the same namespace which means that the more global variables exist, the larger the risk of a conflict.

(I am looking at you, countless forks of PilzAdam's “Simple Mobs” mod which all overwrite the same global variable called “mobs”. >:O )
I'm creating MineClone 2, a Minecraft clone for Minetest.
I made the Help modpack, adding in-game help to Minetest.
 

User avatar
rubenwardy
Member
 
Posts: 4500
Joined: Tue Jun 12, 2012 18:11
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

Re: How to get undeclared global variable warning on interfa

by rubenwardy » Sat Dec 10, 2016 15:55

 

Byakuren
Member
 
Posts: 441
Joined: Tue Apr 14, 2015 01:59
GitHub: raymoo
IRC: Hijiri

Re: How to get undeclared global variable warning on interfa

by Byakuren » Sun Dec 11, 2016 02:52

Wuzzy wrote:(I am looking at you, countless forks of PilzAdam's “Simple Mobs” mod which all overwrite the same global variable called “mobs”. >:O )

Not to mention all of the global variables not called "mobs" that get overwritten by those mods.
Every time a mod API is left undocumented, a koala dies.
 

christoferlevich
Member
 
Posts: 55
Joined: Thu Dec 01, 2016 23:44

Re: How to get undeclared global variable warning on interfa

by christoferlevich » Sun Dec 18, 2016 12:34

Wuzzy wrote:No, the word “local” must be written in front of the variable name, not in front of the file name.

I think it would be best if you beef up your Lua knowledge first and learn about scope, local variables and global variables. :P


I'm working on it. I tend to always jump way ahead of where I should be when learning. Thanks for the response. In time, I won't be so 'green'
 


Return to Modding Discussion

Who is online

Users browsing this forum: No registered users and 73 guests

cron