# sol2 3.5.0 documentation

## variables

### Search the Documentation

# variables

Working with variables is easy with sol, and behaves pretty much like any associative array / map structure you might have dealt with previously.

## reading

Given this lua file that gets loaded into sol:

    1	fullscreen = false,
    2	resolution = { x = 1024, y = 768 }
    3}
    4	)");

You can interact with the Lua Virtual Machine like so:

     1#define SOL_ALL_SAFETIES_ON 1
     2#include <sol/sol.hpp>
     3
     4#include <tuple>
     5#include <utility> // for std::pair
     6
     7int main() {
     8
     9	sol::state lua;
    10	/*
    11	*/
    12	// exactly like a table!
    13	bool isfullscreen
    14	     = lua["config"]
    15	          ["fullscreen"]; // can get nested variables
    16	sol::table config = lua["config"];
    17	int is_defaulted = lua["config"]["fullscreen"].get_or(24);
    18	SOL_ASSERT(is_defaulted == 24);
    19
    20	// This will result in the value of the config, which is
    21	// 'false'
    22	bool is_not_defaulted = lua["config"]["fullscreen"];
    23	SOL_ASSERT(!is_not_defaulted);
    24
    25	return 0;
    26}

From this example, you can see that there’s many ways to pull out the variables you want. For example, to determine if a nested variable exists or not, you can use `auto` to capture the value of a `table[key]` lookup, and then use the `.valid()` method:

     1#define SOL_ALL_SAFETIES_ON 1
     2#include <sol/sol.hpp>
     3
     4#include <tuple>
     5#include <utility> // for std::pair
     6
     7int main() {
     8
     9	sol::state lua;
    10	/*
    11	*/
    12	     = resolution.get<int, int>("x", "y");
    13	SOL_ASSERT(std::get<0>(xyresolutiontuple) == 1024);
    14	SOL_ASSERT(std::get<1>(xyresolutiontuple) == 768);
    15
    16	// test variable
    17	auto bark = lua["config"]["bark"];
    18	if (bark.valid()) {
    19		// branch not taken: config and/or bark are not
    20		// variables
    21	}
    22	int is_defaulted = lua["config"]["fullscreen"].get_or(24);
    23	SOL_ASSERT(is_defaulted == 24);
    24
    25	// This will result in the value of the config, which is
    26	// 'false'
    27	bool is_not_defaulted = lua["config"]["fullscreen"];
    28	SOL_ASSERT(!is_not_defaulted);
    29
    30	return 0;
    31}

This comes in handy when you want to check if a nested variable exists. You can also check if a toplevel variable is present or not by using `sol::optional`, which also checks if A) the keys you’re going into exist and B) the type you’re trying to get is of a specific type:

optional lookup

     1#define SOL_ALL_SAFETIES_ON 1
     2#include <sol/sol.hpp>
     3
     4#include <tuple>
     5#include <utility> // for std::pair
     6
     7int main() {
     8
     9	sol::state lua;
    10	/*
    11	*/
    12	}
    13	else {
    14		// Branch taken: config and bark are existing variables
    15	}
    16
    17	// can also use optional
    18	sol::optional<int> not_an_integer
    19	     = lua["config"]["fullscreen"];
    20	if (not_an_integer) {
    21		// Branch not taken: value is not an integer
    22	}
    23
    24	sol::optional<bool> is_a_boolean
    25	     = lua["config"]["fullscreen"];
    26	if (is_a_boolean) {
    27		// Branch taken: the value is a boolean
    28	int is_defaulted = lua["config"]["fullscreen"].get_or(24);
    29	SOL_ASSERT(is_defaulted == 24);
    30
    31	// This will result in the value of the config, which is
    32	// 'false'
    33	bool is_not_defaulted = lua["config"]["fullscreen"];
    34	SOL_ASSERT(!is_not_defaulted);
    35
    36	return 0;
    37}

This can come in handy when, even in optimized or release modes, you still want the safety of checking. You can also use the get_or methods to, if a certain value may be present but you just want to default the value to something else:

optional lookup

     1#define SOL_ALL_SAFETIES_ON 1
     2#include <sol/sol.hpp>
     3
     4#include <tuple>
     5#include <utility> // for std::pair
     6
     7int main() {
     8
     9	sol::state lua;
    10	/*
    11	*/
    12
    13	sol::optional<double> does_not_exist
    14	     = lua["not_a_variable"];
    15	if (does_not_exist) {
    16		// Branch not taken: that variable is not present
    17	}
    18
    19	// this will result in a value of '24'
    20	// (it tries to get a number, and fullscreen is
    21	// not a number
    22	int is_defaulted = lua["config"]["fullscreen"].get_or(24);
    23	SOL_ASSERT(is_defaulted == 24);
    24
    25	// This will result in the value of the config, which is
    26	// 'false'
    27	bool is_not_defaulted = lua["config"]["fullscreen"];
    28	SOL_ASSERT(!is_not_defaulted);
    29
    30	return 0;
    31}

That’s all it takes to read variables!

## writing

Writing gets a lot simpler. Even without scripting a file or a string, you can read and write variables into lua as you please:

     1#define SOL_ALL_SAFETIES_ON 1
     2#include <sol/sol.hpp>
     3
     4#include <iostream>
     5
     6int main() {
     7
     8	sol::state lua;
     9
    10	// open those basic lua libraries
    11	// again, for print() and other basic utilities
    12	lua.open_libraries(sol::lib::base);
    13
    14	// value in the global table
    15	lua["bark"] = 50;
    16
    17	// a table being created in the global table
    18	lua["some_table"] = lua.create_table_with("key0",
    19	     24,
    20	     "key1",
    21	     25,
    22	     lua["bark"],
    23	     "the key is 50 and this string is its value!");
    24
    25	// Run a plain ol' string of lua code
    26	// Note you can interact with things set through sol in C++
    27	// with lua! Using a "Raw String Literal" to have multi-line
    28	// goodness:
    29	// http://en.cppreference.com/w/cpp/language/string_literal
    30	lua.script(R"(
    31
    32	print(some_table[50])
    33	print(some_table["key0"])
    34	print(some_table["key1"])
    35
    36	-- a lua comment: access a global in a lua script with the _G table
    37	print(_G["bark"])
    38
    39	)");
    40
    41	return 0;
    42}

This example pretty much sums up what can be done. Note that the syntax `lua["non_existing_key_1"] = 1` will make that variable, but if you tunnel too deep without first creating a table, the Lua API will panic (e.g., `lua["does_not_exist"]["b"] = 20` will trigger a panic). You can also be lazy with reading / writing values:

     1#define SOL_ALL_SAFETIES_ON 1
     2#include <sol/sol.hpp>
     3
     4#include <iostream>
     5
     6int main() {
     7
     8	sol::state lua;
     9
    10	auto barkkey = lua["bark"];
    11	if (barkkey.valid()) {
    12		// Branch not taken: doesn't exist yet
    13		std::cout << "How did you get in here, arf?!"
    14		          << std::endl;
    15	}
    16
    17	barkkey = 50;
    18	if (barkkey.valid()) {
    19		// Branch taken: value exists!
    20		std::cout << "Bark Bjork Wan Wan Wan" << std::endl;
    21	}
    22
    23	return 0;
    24}

Finally, it’s possible to erase a reference/variable by setting it to `nil`, using the constant `sol::lua_nil` in C++:

     1#define SOL_ALL_SAFETIES_ON 1
     2#include <sol/sol.hpp>
     3
     4#include <iostream>
     5
     6int main() {
     7
     8	sol::state lua;
     9	lua["bark"] = 50;
    10	sol::optional<int> x = lua["bark"];
    11	// x will have a value
    12	if (x) {
    13		std::cout << "x has no value, as expected"
    14		          << std::endl;
    15	}
    16	else {
    17		return -1;
    18	}
    19
    20	lua["bark"] = sol::lua_nil;
    21	sol::optional<int> y = lua["bark"];
    22	// y will not have a value
    23	if (y) {
    24		return -1;
    25	}
    26	else {
    27		std::cout << "y has no value, as expected"
    28		          << std::endl;
    29	}
    30
    31	return 0;
    32}

It’s easy to see that there’s a lot of options to do what you want here. But, these are just traditional numbers and strings. What if we want more power, more capabilities than what these limited types can offer us? Let’s throw some functions in there C++ classes into the mix!