1
votes

According to Lua's manual

Global variables do not need declarations. You simply assign a value to a global variable to create it. It is not an error to access a non-initialized variable; you just get the special value nil as the result

I think declaration is good, it makes thing more manageable. Why did Lua skip declarations for Global variables? I guess they have a good reason but I don't know why.

What if I make this mistake

-- Activation Code
function TestLoco:OnActivate()
    self.MyGlobal = "ABC"; --Init the global variable
end

-- Run every tick
function TestLoco:OnTick()
    self.MyGIobaI = "BCD"; --Edit the global variable at every tick, but I mistake 'I' with 'l'
end

-- Call when I click the mouse
function TestLoco:OnClick()
    Debug.Log(self.MyGlobal); --This print "ABC", but It should be "BCD", what if I don't notice this?
end
1
Then you would see an incorrect value being displayed and would have to find out what you did wrong, which is misspelled the variable. Can always copy and paste the variable. - Rimble
@Rimble: Thanks for your comment, it's just an example to make my point clear, I'm thinking about more complex script which the bug hide deep down in the code and can only be detected when a very special condition match. So you mean when write Lua, we can only rely on our human eye - which is very deceitful (I don't trust myself) - 123iamking
1) Usage of globals in Lua is ... somewhat deprecated. 2) strict.lua is the must for Lua programming. I use it always. 3) You can create metamethod-based utility for defining allowed fields in a table. - Egor Skriptunoff
Thank Egor Skriptunoff :) - 123iamking
There really isn't such a thing as globals in Lua. It's more about scoping. Everything is tables in lua and you can set the environment, which really just change which table is manipulated on index and newindex. The default environment is just table _G._G. If you use setfenv with a new table on a loadstring, you'll see it won't have access to anything in _G unless you specifically set metamethods to look there. By default when you do foo = bar, it's really as if you wrote _G.foo = bar. If setfenv was set to sometable, it would be literally sometable.foo = bar, when you executed foo = bar. - Alundaio

1 Answers

1
votes

Because Lua has no classes. self.MyGlobal is not a global variable, it is a field in the table passed via the self parameter. The syntax is equivalent to self["MyGlobal"]. For a "true" global variable assignment (e.g. x = 0), it is equivalent to _G["x"] = 0, where _G is the global environment table.

Since Lua has no notion of classes, the type of self is simply a table. The syntax you use for specifying a "method" is just a syntactic shortcut to this:

TestLoco.OnActivate = function(self)
    self["MyGlobal"] = "ABC";
end

It's just a function that assigns a field in a table. It could be called with potentially any table, hence it cannot verify the table actually should have that field.

However, Lua offers some pretty good run-time customisable checking via metatables. If you build a table specifying the "class" of a table, you can assign a metatable to every table that checks the assignment each time if it assigns to a field that you actually "declared".