how to test if variable is already declared?


(g8tr1522) #1

Hi

Why can’t I do this?

if a then 
	print("`a` already exists as a global!")
end

or this?

a = a or 1

I get this error message :

*** TestPad.lua:10: variable ‘a’ is not declared

*** stack traceback:

*** [C]: in function ‘_error’

*** [string “local mt = getmetatable(_G)…”]:29: in function <[string “local mt = getmetatable(_G)…”]:24>

*** TestPad.lua:10: in main chunk

These are totally valid code chunks in vanilla lua.

Obviously, this has to do with the global environment, but that still mystifiesme, even in vanilla Lua.

My guess is that I’m expecting

_G.__metatable[“a”]

to return nil, but clearly, there’s more going on than that.

I’m wondering because I use a global string to load files in a couple of projects. Both projects use the same name for the identifier: _mainroot. To avoid conflicts, I’m stashing_mainrootinside another varaible,_old_mainroot, and then loading it back into_mainrootat the end of the file. But I can’t do that if I can’t do the above.

As a quick workaround, I just added the statement _mainroot = '' into the file which requires those two projects.


(joule) #2

Does that really work in vanilla LUA? To me it looks like a syntax that wouldn’t make any sense. Either a variable is declared intentionally (at the same scope or a higher scope) - or it’s not.

If you really need to do this (for some strange reason?), this might be a workaround? Otherwise, the natural thing is to always declare variables (“local a”) before wanting to access them.

function exists(var)
  for k, _ in pairs(_G) do
    if k == var then
      return true
    end
  end
end

if exists("some_variable_name") then
  print("global variable exists")
end

PS. I don’t understand the use case exactly. I assume that you know that each tool has its own _G table, even if you require the same file from multiple tools.


(g8tr1522) #3

Well I just read your post from the xStream thread. Specifically, where you mentioned that Renoise uses Lua 5.1. Which I never knew until today… lol

What I’m doing may be a Lua 5.3 thing.

Guess I’m gonna have to figure out how to build Lua from source again…

And to be more specific about my use-case:

I use a global string to require files. If my project is required in some file, and that file isn’t in the same folder as the project’s main file, then I use a global string which tells the project’s main file where to find its other files.

I could go on, but that deserves another post I think. Plus, it works alright so far, even if it may not be the best method.


(joule) #4

One option is to use pcall() to test and catch something that might fail, but without triggering a verbose error. Instead, it will return false if the function call returned an error.

https://www.lua.org/manual/5.1/manual.html#pdf-pcall


(danoise) #5

One option is to use pcall() to test and catch something that might fail, but without triggering a verbose error. Instead, it will return false if the function call returned an error.

Yep! it’s the try … catch of the lua world


#6

What I’m doing may be a Lua 5.3 thing.

I think you’ll find that ‘nil’ will be returned also in vanilla lua 5.1 with a undeclared/no storage specifier/no assigned variable.

> print(_VERSION)
Lua 5.1
> print(a)
nil

To try and answer as to why vanilla lua doesn’t throw an error and Renoise lua does I would suggest/speculate that that is because Renoise lua has a _STRICT code (addon to catch undefined variables) defined in the lua interpreter. For example (with the Renoise terminal):

>>> print(a)
*** [string "print(a)"]:1: variable 'a' is not declared
*** stack traceback:
*** [C]: in function '_error'
*** [string "local mt = getmetatable(_G)..."]:29: in function <[string "local mt = getmetatable(_G)..."]:24>
*** [string "print(a)"]:1: in main chunk

>>> _STRICT=false -- set _STRICT to false

>>> print(a)
nil

(joule) #7

4Tey dropping knowledge :o

Do you know if _STRICT has any other implications?


#8

Do you know if _STRICT has any other implications?

Wouldn’t really of said there are other implications for certain Joule, (but I’m not a lua expert…best person to ask would be taktik/danoise/you I suppose) You could possibly see the ‘strict’ code yourself here if it helps -> http://metalua.luaforge.net/src/lib/strict.lua.html


(ffx) #9

Maybe check lua type():https://www.lua.org/pil/2.html

It is the pendant to typeof() in javascript:

print(type(a)) --> nil (`a' is not initialized)

So

if type(a) == nil then ...

EDIT: Ok that does not work in LUA, still throws an error.