the variable scope in tcl - variables

I have a question about variable scope in TCL, I have the following code:
namespace eval ::hello {
variable player
variable name
namespace export *
}
proc ::hello::setPlay {value} {
set ::hello::player
}
proc ::hello::getPlay {} {
return $::hello::player
}
proc ::hello::setName {value} {
set ::hello::name
}
proc ::hello::getName {} {
return $::hello::name
}
proc GET_NAME {} {
#here I have a variable called name as well
set name "RON"
return $name
}
in the GET_NAME,if I set the variable name as "RON", does it will set the variable name declaired in namespace? can I have the same variable name in GET_NAME and namespace? And if I add this line variable name in GET_NAME, does this mean, it will set the variable declaired in name space?

Variables in procedures (and lambda expressions) default to being local to that procedure. If explicitly declared to be something else (e.g., with global, upvar or variable) then that actually couples a local variable to another variable elsewhere so that acting on one (e.g., reading or writing) is exactly like acting on the other. If you use a variable name with :: in it, that is a reference to a namespaced variable (the global namespace is just ::) which might be resolved either relative to the current namespace or the global namespace, depending on whether the name starts with :: or not. (Think of it a bit like a slash in a filename.)
When executing code inside namespace eval, always use variable to declare variables before using them. This avoids problems with global variable shadowing that are really horrible but necessary to keep due to some existing code depending on them. (Technically, you don't need to do this in namespace eval :: as global variables can't shadow themselves, but it doesn't hurt.)
Dealing with specifics:
in the GET_NAME,if I set the variable name as "RON", does it will set the variable name declaired in namespace?
No, not with the code you wrote.
can I have the same variable name in GET_NAME and namespace?
You can use the same name of variable in the two places. This can be confusing, but it limits surprises overall.
And if I add this line variable name in GET_NAME, does this mean, it will set the variable declaired in name space?
Yes. Exactly that. (It couples the two together precisely.)

Related

How to declare a global variable inside a function

I am not able to find the required solution. I want to call a function and want to use some variable which is being declared in that function(I don't want to return that variable). I just want to make it global.
func foo(){
temp:=30
}
func main(){
foo()
// How to use temp without returning or without declaring it outside foo and main
}
You can't. You can only declare a package variable (aka global variable) in package scope. You can modify it from inside a function, but you can't declare it inside a function. This is because anything else referring to that variable has to have that reference resolvable at compile time. Otherwise, what happens when Bar() tries to reference the variable before Foo() could declare it? That would break compile-time safety that Go guarantees.
That said, the solution is simple; just declare it in package scope. It's unclear in the question why you wouldn't want to do that - if you want a global, that's what you do.

variable hides a variable in an enclosing block error

The code
Using m_objSqlConnection = New SqlCeConnection(m_strConnectionString)
End Using
produces the following error:
Variable 'm_objSqlConnection' hides a variable in an enclosing block
The "m_" prefix suggests that you have a member variable with that name. When you use a Using statement you are declaring a variable that exists only in the scope of that block. If you already have a member variable with that name then why would you want a local variable with the same name? You need to decide whether a local variable or a member variable is more appropriate and stick with the one option. If you're disposing the connection at the end of the Using block then you're apparently not reusing it so I'd think that getting rid of the member variable is the way to go.

In Emacs how do I make a local variable safe to be set in a file for all possible values

In Elisp I have introduced for a special custom mode a variable like:
(defvar leo-special-var "")
(make-variable-buffer-local 'leo-special-var)
Now I set this variable in files I with the lines (in the file to edit):
# Local Variables:
# leo-special-var: "-d http://www.google.com.au"
# End:
And I want to consider this variable as "safe for all its values. That's why safe-local-variable-values doesn't help. Instead I tried (in the lisp code):
# setting the symbol property of the variable
(put 'leo-special-var 'safe-local-variable 'booleanp)
but without success. Do I do something wrong when setting the symbol property? Or is there another way?
You want to use
(put 'leo-special-var 'safe-local-variable #'stringp)
to say that it is safe as long as it's a string.
If you really want to state that it is safe for all values then use this:
(put 'leo-special-var 'safe-local-variable (lambda (_) t))
The function to test safety here returns non-nil for any value.
(But I'd think that you probably do not want to state that a variable is safe for any value.)
It's in the manual: (elisp) File Local Variables
You can specify safe values for a variable with a
`safe-local-variable' property. The property has to be a function of
one argument; any value is safe if the function returns non-`nil' given
that value. Many commonly-encountered file variables have
`safe-local-variable' properties; these include `fill-column',
`fill-prefix', and `indent-tabs-mode'. For boolean-valued variables
that are safe, use `booleanp' as the property value. Lambda
expressions should be quoted so that `describe-variable' can display
the predicate.
When defining a user option using `defcustom', you can set its
`safe-local-variable' property by adding the arguments `:safe FUNCTION'
to `defcustom' (*note Variable Definitions::).

lua variables scope

I am aware there are other similar topics but could not find an straight answer for my question.
Suppose you have a function such as:
function aFunction()
local aLuaTable = {}
if (something) then
aLuaTable = {}
end
end
For the aLuaTable variable inside the if statement, it is still local right?. Basically what I am asking is if I define a variable as local for the first time and then I use it again and again any number of times will it remain local for the rest of the program's life, how does this work exactly?.
Additionally I read this definition for Lua global variables:
Any variable not in a defined block is said to be in the global scope.
Anything in the global scope is accessible by all inner scopes.
What is it meant by not in a defined block?, my understanding is that if I "declare" a variable anywhere it will always be global is that not correct?.
Sorry if the questions are too simple, but coming from Java and objective-c, lua is very odd to me.
"Any variable not in a defined block is said to be in the global scope."
This is simply wrong, so your confusion is understandable. Looks like you got that from the user wiki. I just updated the page with the correction information:
Any variable that's not defined as local is global.
my understanding is that if I "declare" a variable anywhere it will always be global
If you don't define it as local, it will be global. However, if you then create a local with the same name, it will take precedence over the global (i.e. Lua "sees" locals first when trying to resolve a variable name). See the example at the bottom of this post.
If I define a variable as local for the first time and then I use it again and again any number of times will it remain local for the rest of the program's life, how does this work exactly?
When your code is compiled, Lua tracks any local variables you define and knows which are available in a given scope. Whenever you read/write a variable, if there is a local in scope with that name, it's used. If there isn't, the read/write is translated (at compile time) into a table read/write (via the table _ENV).
local x = 10 -- stored in a VM register (a C array)
y = 20 -- translated to _ENV["y"] = 20
x = 20 -- writes to the VM register associated with x
y = 30 -- translated to _ENV["y"] = 30
print(x) -- reads from the VM register
print(y) -- translated to print(_ENV["y"])
Locals are lexically scoped. Everything else goes in _ENV.
x = 999
do -- create a new scope
local x = 2
print(x) -- uses the local x, so we print 2
x = 3 -- writing to the same local
print(_ENV.x) -- explicitly reference the global x our local x is hiding
end
print(x) -- 999
For the aLuaTable variable inside the if statement, it is still local right?
I don't understand how you're confused here; the rule is the exact same as it is for Java. The variable is still within scope, so therefore it continues to exist.
A local variable is the equivalent of defining a "stack" variable in Java. The variable exists within the block scope that defined it, and ceases to exist when that block ends.
Consider this Java code:
public static void main()
{
if(...)
{
int aVar = 5; //aVar exists.
if(...)
{
aVar = 10; //aVar continues to exist.
}
}
aVar = 20; //compile error: aVar stopped existing at the }
}
A "global" is simply any variable name that is not local. Consider the equivalent Lua code to the above:
function MyFuncName()
if(...) then
local aVar = 5 --aVar exists and is a local variable.
if(...) then
aVar = 10 --Since the most recent declaration of the symbol `aVar` in scope
--is a `local`, this use of `aVar` refers to the `local` defined above.
end
end
aVar = 20 --The previous `local aVar` is *not in scope*. That scope ended with
--the above `end`. Therefore, this `aVar` refers to the *global* aVar.
end
What in Java would be a compile error is perfectly valid Lua code, though it's probably not what you intended.

Function/variable scope (pass by value or reference?)

I'm completely confused by Lua's variable scoping and function argument passing (value or reference).
See the code below:
local a = 9 -- since it's define local, should not have func scope
local t = {4,6} -- since it's define local, should not have func scope
function moda(a)
a = 10 -- creates a global var?
end
function modt(t)
t[1] = 7 -- create a global var?
t[2] = 8
end
moda(a)
modt(t)
print(a) -- print 9 (function does not modify the parent variable)
print(t[1]..t[2]) -- print 78 (some how modt is modifying the parent t var)
As such, this behavior completely confuses me.
Does this mean that table variables
are passed to the function by
reference and not value?
How is the global variable creation
conflicting with the already define
local variable?
Why is modt able to
modify the table yet moda is not able
to modify the a variable?
You guessed right, table variables are passed by reference. Citing Lua 5.1 Reference Manual:
There are eight basic types in Lua: nil, boolean, number, string, function, userdata, thread, and table.
....
Tables, functions, threads, and (full) userdata values are objects: variables do not actually contain these values, only references to them. Assignment, parameter passing, and function returns always manipulate references to such values; these operations do not imply any kind of copy.
So nil, booleans, numbers and strings are passed by value. This exactly explains the behavior you observe.
Lua's function, table, userdata and thread (coroutine) types are passed by reference. The other types are passed by value. Or as some people like to put it; all types are passed by value, but function, table, userdata and thread are reference types.
string is also a kind of reference type, but is immutable, interned and copy-on-write - it behaves like a value type, but with better performance.
Here's what's happening:
local a = 9
local t = {4,6}
function moda(a)
a = 10 -- sets 'a', which is a local introduced in the parameter list
end
function modt(t)
t[1] = 7 -- modifies the table referred to by the local 't' introduced in the parameter list
t[2] = 8
end
Perhaps this will put things into perspective as to why things are the way they are:
local a = 9
local t = {4,6}
function moda()
a = 10 -- modifies the upvalue 'a'
end
function modt()
t[1] = 7 -- modifies the table referred to by the upvalue 't'
t[2] = 8
end
-- 'moda' and 'modt' are closures already containing 'a' and 't',
-- so we don't have to pass any parameters to modify those variables
moda()
modt()
print(a) -- now print 10
print(t[1]..t[2]) -- still print 78
jA_cOp is correct when he says "all types are passed by value, but function, table, userdata and thread are reference types."
The difference between this and "tables are passed by reference" is important.
In this case it makes no difference,
function modt_1(x)
x.foo = "bar"
end
Result: both "pass table by reference" and "pass table by value, but table is a reference type" will do the same: x now has its foo field set to "bar".
But for this function it makes a world of difference
function modt_2(x)
x = {}
end
In this case pass by reference will result in the argument getting changed to the empty table. However in the "pass by value, but its a reference type", a new table will locally be bound to x, and the argument will remain unchanged. If you try this in lua you will find that it is the second (values are references) that occurs.
I won't repeat what has already been said on Bas Bossink and jA_cOp's answers about reference types, but:
-- since it's define local, should not have func scope
This is incorrect. Variables in Lua are lexically scoped, meaning they are defined in a block of code and all its nested blocks.
What local does is create a new variable that is limited to the block where the statement is, a block being either the body of a function, a "level of indentation" or a file.
This means whenever you make a reference to a variable, Lua will "scan upwards" until it finds a block of code in which that variable is declared local, defaulting to global scope if there is no such declaration.
In this case, a and t are being declared local but the declaration is in global scope, so a and t are global; or at most, they are local to the current file.
They are then not being redeclared local inside the functions, but they are declared as parameters, which has the same effect. Had they not been function parameters, any reference inside the function bodies would still refer to the variables outside.
There's a Scope Tutorial on lua-users.org with some examples that may help you more than my attempt at an explanation. Programming in Lua's section on the subject is also a good read.
Does this mean that table variables are passed to the function by reference and not value?
Yes.
How is the global variable creation conflicting with the already define local variable?
It isn't. It might appear that way because you have a global variable called t and pass it to a function with an argument called t, but the two ts are different. If you rename the argument to something else, e,g, q the output will be exactly the same. modt(t) is able to modify the global variable t only because you are passing it by reference. If you call modt({}), for example, the global t will be unaffected.
Why is modt able to modify the table yet moda is not able to modify the a variable?
Because arguments are local. Naming your argument a is similar to declaring a local variable with local a except obviously the argument receives the passed-in value and a regular local variable does not. If your argument was called z (or was not present at all) then moda would indeed modify the global a.