Defining global variables

Posted by Batista on Sat 26 Aug 2006 12:09 AM — 19 posts, 92,097 views.

#0
Okay, I already know that once the solution is posted I'll smack myself in the head and scream, "WHY DIDN'T I THINK OF THAT?!" But anywho...

For some reason, I'm having a ton of trouble trying to create a global variable in the script file. I'll readily admit that I'm a total newbie when it comes to using the script file, but I figured this would work:

global testvar = GetVariable("value")


or


global testvar

testvar = GetVariable("value")


I'm totally out of ideas. I'm not even sure if it's worth it. I'm wanting to save code time in triggers and aliases by not having to constantly redefine the same local variables I use in other scripts. :/
Australia Forum Administrator #1
Quote:

testvar = GetVariable("value")


All variables are global in Lua by default, so that is all you have to do.

Inside a function, you can localize a variable like this:


function test (blah)
 local i, j = 5, 6

 print (i, j)

 foo = 42
end -- test


In this case both i and j are local to the function test. However foo is a global variable.
#2
Quote:
local i, j = 5, 6


I'm a complete lua newbie as well, what does that mean exactly?
Amended on Mon 08 Jan 2007 01:48 PM by Gore
USA #3
That declares two local variables, i and j, and assigns 5 to i and 6 to j.

In Lua, a list of values assigned to a list of variables will assign them one by one in the same order as they're given; excess values are thrown away and if a variable has no value it is set to nil.

E.g. a,b = 1 means b will be nil.

a,b = 1,2,3 means that a==1, b==2 and the 3 is thrown away.
#4
thanks a bunch, how come in the tutorial it says you declare a variable with var ::=name or somesuch, but you can use global name or local name here?
USA #5
Much like any other language, Lua offers several declaration methods for variables. What the tutorial offers is the "textbook" examples that most new users will be most comfortable learning because they offer the "most sound" programming structure.
#6
Ahhh I see. What would be the most "correct" way of doing things, doesit not really matter?

USA #7
Generally you want all variables to be local unless they have to be global. It's cleaner, and avoids leaving variables all over the place. More importantly, it can prevent somewhat subtle bugs in code, if two functions rely on the same variable that should be local but gets modified somewhere else.
#8
So basically

var ::=variablename
Creates a global variable called variablename

variablename="whatever"

creates a global variable called variablename with the string "whatever" in it

local variablename="whatever"

does the same, but locally?

or even just

local variablename
global variablename

to make variables without anything in them?

target=""
Note (target)

function Target_Player (n,o,wildcard)
	target=wildcard[1];
end


Weird, if I put a global before the target I get the error:

Error number: 0
Event:        Compile error
Description:  [string "Script file"]:73: `=' expected near `target'
Called by:    Immediate execution

Amended on Wed 10 Jan 2007 06:47 AM by Gore
USA #9
I've never seen Lua use the ::= notation. You don't need it, in any case. You might be confusing it with the manual's statement of the language grammar, e.g.
Quote:

    stat ::= varlist1 `=´ explist1
    varlist1 ::= var {`,´ var}
    explist1 ::= exp {`,´ exp}

Those aren't actually Lua statements; it's a meta-statement, if you will, describing what Lua code looks like.

If you don't prefix the first use of a variable in a given lexical scope with local, then it is global.

e.g.
local foo = 2 -- foo is now local in this scope
fo = 3 -- oops, created a new global variable


There is no way that I know of to create an empty global variable, other than perhaps just:
someglobal = nil
but I'm not sure why you'd want to do that.

However, typing just
local foo
means that from that point on in the lexical scope, foo will be local.
#10
Ah heh. On my old mud, I would use a ton of variables for different things, on Lua is it worth it to group which variables I can by tables?

Say, if I have 4 variables for targetting, should I make a targetting table?

dim target, target_one, target_two, target_three

target =
	{
	cur = "",
	one = "",
	two = "",
	three = "",
	}


or is it not worth it? or is it more of a "do whatever you want" type of thing? heh
USA #11
I guess it depends. Having a table can make it easier to pass around a bunch of variables at the same time. It also lets you group things, which might be useful in some circumstances. Either way the usefulness is stylistic, not functional, I think. (But don't underestimate the importance of correct/good style.) Just do what makes the most sense to you, I suppose. :)
Australia Forum Administrator #12
Quote:

or even just

local variablename
global variablename

...

Weird, if I put a global before the target I get the error:



There is no "global variablename" syntax - you can forget that, it was a guess by the original poster.

Variables are global by default (strictly speaking, they are looked up in the environment table that applies to the current function).

However if, in the lexical scope of a variable reference, that variable has been declared local, or is a function argument, then no table lookup occurs and the local variable is used.

You can't just look at a line like this:


a = 42


... and assume a global variable is being created/assigned. You would need to see if, further back, there was a local statement declaring "a", or if it is a function argument to the current function, or a parent function.

Quote:

... to make variables without anything in them?


There is no way of making a global variable with nothing in it. Doing this for example, simply deletes a current global variable, if one exists:


a = nil


It does not create an "empty" variable named "a".

You can, however make an empty local variable, eg.


local a = nil


In this case "= nil" is redundant, it would default to nil.


Australia Forum Administrator #13
Quote:

Say, if I have 4 variables for targetting, should I make a targetting table?


The usefulness of a table like you describe is, that you can pass the table around, as the table reference is passed (eg. to function calls).

So you could have:


function f (t)
  t.one = "Nick"
end -- function f

target =
	{
	cur = "",
	one = "",
	two = "",
	three = "",
	}

f (target)

print (target.one) --> Nick


However without using the table, parameters are passed by value, and this would not work:


function f (x)
  x = "Nick"
end -- function f


local target, target_one, target_two, target_three

f (target_one)

print (target_one)  --> nil


In this case we are passing target_one down *by value* and not by reference, so changing it inside a function merely changes the local copy. You may not want this.

Effectively, inside function f, the variable x is local, however it is initialized with the value that the function caller gives it.


#14
Lua is so much neater and more interesting than vbscript.
#15
Style wise: which is a better way to see if a variable is true?

if variable == 1 then
--blah
end

or

if variable then
--blah
end

?
USA #16
The second one is probably better of those two. For the first, you should test against true, not one. Otherwise, you have to worry about it being 2, 3, 4, and so forth. (Lua has the boolean type, so it should be used.)

The second case will be true unless the variable is nil or false.

Come to think of it, if the variable is 0, it will be true as well, which might or might not be what you want.

Testing against 'true' is probably what you want, really. And if you're not testing against a boolean, then you should have whatever test you are looking for, e.g. if var > 0 or whatever.

Stylistically it's generally better to make explicit conditions just so it's clear what's going on.
Australia Forum Administrator #17
I don't like:


if variable == true then


The "if" test is already checking if the expression is true or not, and thus it is like saying "if this is true is true".

Quote:

Lua has the boolean types ...


This is true, however Lua values can have boolean types, Lua variables are untyped. Thus you can't make a variable a boolean, it just might happen to contain a boolean value at a certain time.

A variable might in fact contain nil (which would be considered false in an "if" statement), or true or false.

Only two value are considered false in an "if" test: nil and false. Anything else is true, including numeric zero.

I certainly wouldn't say:


if variable == 1 then


The implication is that a value of 0 is false, whereas 0 is still considered true.

Of course, you could write:


if variable == 0 then
-- this is the false branch
end -- if


But I think that is rather convoluted.
Australia Forum Administrator #18
In case I haven't made myself clear in the above post:

  • I would use the boolean type (ie. true or false) rather than 0/1
  • I would say:


    if variable then ...


    ... rather then "if x == true" or "if x == 1"
  • In extreme cases you could use the value nil to indicate "I don't know if it is true or false". However otherwise, uninitialized variables will default to nil, which is effectively false.