Nil fix?

Hello, can someone tell me how to fix the nil problem.

For example, this code here will cause the entire script to fail:


if (test[1][2][3] == 1) then
 // Stuff
end

I have to use this instead:


if (test!=nil and test[1]!=nil and test[1][2]!=nil and test[1][2][3]==1) then
 // Stuff
end

It’s very frustrating. Unless I have tons of nil checks everywhere in the scripts, it fails. Thanks for any help.


if test and test[ 1 ] and test[ 1 ][ 2 ] and test[ 1 ][ 2 ][ 3 ] == 1 then
  --stuff
end

nil evaluates to false, so you can do that. Of course, this assumes that test[ 1 ] and test[ 1 ][ 2 ] are tables.

They are not tables yet, so I have to use the 2nd code. Having to check for nils in every array in my code is tedious and annoying.

Like again if I want to do something a little more complex like:


if (test[1][2][3] == 1 or test[5][6][7] == 1) then
 // Stuff
end

I have to use this instead…


if ((test!=nil and test[1]!=nil and test[1][2]!=nil and test[1][2][3]==1) or (test!=nil and test[5]!=nil and test[5][6]!=nil and test[5][6][7]==1)) then
 // Stuff
end

You can see how this can become hugely complex after only a few array comparisons.

You definitely need to rethink your design if you are going to have a table like that. What are you trying to do?

I use complex arrays for many purposes, such as storing user information. I have to compare the arrays in many different places and I can’t create the tables first. Is there no way around it or some way of disabling nil errors? Problems like this are non-existent in PHP.

Arrays and table in Lua are the same thing.

You could do this:



datatable = { }
function SetVar( ply, var, val )
  datatable[ ply ] = datatable[ ply ] or { }
  datatable[ ply ][ var ] = val
end

function GetVar( ply, var, default )
  datatable[ ply ] = datatable[ ply ] or { }
  return datatable[ ply ][ var ] or default
end

function IncrementVar( ply, var, amount )
  amount = amount or 1

  SetVar( ply, var, GetVar( ply, var, 0 ) + amount )
end


So you could then do this, for example:



local function PlayerSpawn( pl )
  IncrementVar( pl, "TimesSpawned" )

  if GetVar( pl, "TimesSpawned", 0 ) == 10 then
    pl:ChatPrint( "You have spawned 10 times so far!" )
  end
end

hook.Add( "PlayerSpawn", "Count Times Spawned", PlayerSpawn )


When dealing with any kind of data structure that wraps a table or array, you really should abstract it to make accessing it easier and less of a hassle.

In the example above, doing that as arbitrary code any time you want to access datatable[ pl ][ var ] would be tedious at best as you have to check to make sure all the parent tables are valid along the line. With the code that I posted, it becomes as simple as GetVar( pl, var, default ).

Just try to make your life easier rather than using code that makes it harder.

I hope I’m not going to blow anyone’s mind here, but you do realise that player objects act like tables, so you can store the data related to the player directly on the player rather than having this sort of thing?

I used an example related to what his code was doing. What you brought up is the better ( probably best ) way.