Jump to content


Photo

how to test if variable is already declared?

existence global variable test scripting

  • Please log in to reply
8 replies to this topic

#1 g8tr1522

g8tr1522

    Member

  • Normal Members
  • PipPip
  • 32 posts
  • Gender:Male
  • Location:Gainesville, FL

Posted 08 January 2018 - 17:34

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 mystifies me, 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 _mainroot inside another varaible, _old_mainroot, and then loading it back into _mainroot at 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.

Edited by g8tr1522, 08 January 2018 - 17:40.


#2 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • 1694 posts
  • Gender:Not Telling
  • Location:Sweden
  • Interests:music, philosophy, engineering

Posted 08 January 2018 - 17:48

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.

Edited by joule, 08 January 2018 - 18:06.


#3 g8tr1522

g8tr1522

    Member

  • Normal Members
  • PipPip
  • 32 posts
  • Gender:Male
  • Location:Gainesville, FL

Posted 08 January 2018 - 20:20

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.


Edited by g8tr1522, 08 January 2018 - 20:22.


#4 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • 1694 posts
  • Gender:Not Telling
  • Location:Sweden
  • Interests:music, philosophy, engineering

Posted 09 January 2018 - 11:46

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/....html#pdf-pcall


  • Ledger likes this

#5 danoise

danoise

    Probably More God or Borg Than Human Member

  • Renoise Team
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 6793 posts
  • Gender:Male
  • Location:Berlin
  • Interests:wildlife + urban trekking

Posted 09 January 2018 - 11:57

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


Tracking with Stuff. API wishlist | Soundcloud


#6 4Tey

4Tey

    Big Daddy Member

  • Normal Members
  • PipPipPipPipPipPipPip
  • 447 posts
  • Gender:Male

Posted 09 January 2018 - 17:14

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 likes this

#7 joule

joule

    Guruh Motha Fakka is Levitating and Knows Everything About Renoise Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPip
  • 1694 posts
  • Gender:Not Telling
  • Location:Sweden
  • Interests:music, philosophy, engineering

Posted 09 January 2018 - 17:39

4Tey dropping knowledge :o

 

Do you know if _STRICT has any other implications?


  • 4Tey likes this

#8 4Tey

4Tey

    Big Daddy Member

  • Normal Members
  • PipPipPipPipPipPipPip
  • 447 posts
  • Gender:Male

Posted 09 January 2018 - 17:48

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.luafo...strict.lua.html


Edited by 4Tey, 09 January 2018 - 18:13.


#9 ffx

ffx

    Composes without Wires burns Directly from Brain to DVD that is already in Store Member

  • Normal Members
  • PipPipPipPipPipPipPipPipPipPipPipPipPipPip
  • 3304 posts
  • Gender:Not Telling

Posted 09 January 2018 - 19:37

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.


Edited by ffx, 07 February 2018 - 15:47.

Test system: macOS 10.13.4, HFS+. Firewire Audio, i7 4770, 8GB Ram, GTX1050 2GB, 48kHz






Also tagged with one or more of these keywords: existence, global, variable, test, scripting