[ci skip] read only documentation

This commit is contained in:
ThePhD 2016-11-04 19:56:48 -04:00
parent 76bed7a09c
commit bd83b3bb65
2 changed files with 83 additions and 26 deletions

View File

@ -18,36 +18,36 @@ Here's a complete working example of it working for Lua 5.3 and Lua 5.2, and how
lua.open_libraries(); lua.open_libraries();
lua.script(R"( lua.script(R"(
function f (x) function f (x)
print('--- Calling f ---') print('--- Calling f ---')
for k, v in ipairs(x) do for k, v in ipairs(x) do
print(k, v) print(k, v)
end
end end
end )");
)");
// Have the function we // Have the function we
// just defined in Lua // just defined in Lua
sol::function f = lua["f"]; sol::function f = lua["f"];
// Set a global variable called // Set a global variable called
// "arr" to be a vector of 5 lements // "arr" to be a vector of 5 lements
lua["arr"] = std::vector<int>{ 2, 4, 6, 8, 10 }; lua["arr"] = std::vector<int>{ 2, 4, 6, 8, 10 };
// Call it, see 5 elements // Call it, see 5 elements
// printed out // printed out
f(lua["arr"]); f(lua["arr"]);
// Mess with it in C++ // Mess with it in C++
std::vector<int>& reference_to_arr = lua["arr"]; std::vector<int>& reference_to_arr = lua["arr"];
reference_to_arr.push_back(12); reference_to_arr.push_back(12);
// Call it, see *6* elements // Call it, see *6* elements
// printed out // printed out
f(lua["arr"]); f(lua["arr"]);
return 0; return 0;
} }
Note that this will not work well in 5.1, as it has explicit table checks and does not check metamethods, even when ``pairs`` or ``ipairs`` is passed a table. In that case, you will need to use a more manual iteration scheme. Note that this will not work well in 5.1, as it has explicit table checks and does not check metamethods, even when ``pairs`` or ``ipairs`` is passed a table. In that case, you will need to use a more manual iteration scheme.

View File

@ -1,6 +1,6 @@
readonly readonly
======== ========
Routine to mark a member variable as read-only routine to mark a member variable as read-only
---------------------------------------------- ----------------------------------------------
.. code-block:: cpp .. code-block:: cpp
@ -8,4 +8,61 @@ Routine to mark a member variable as read-only
template <typename T> template <typename T>
auto readonly( T&& value ); auto readonly( T&& value );
The goal of read-only is to protect a variable set on a usertype or a function. Simply wrap it around a member variable, e.g. ``sol::readonly( &my_class::my_member_variable )`` in the appropriate place to use it. If someone tries to set it, it will throw an error. The goal of read-only is to protect a variable set on a usertype or a function. Simply wrap it around a member variable, e.g. ``sol::readonly( &my_class::my_member_variable )`` in the appropriate place to use it. If someone tries to set it, it will throw an error. This can ONLY work on :doc:`usertypes<usertype>` and when you specifically set a member variable as a function and wrap it with this. It will NOT work anywhere else: doing so will invoke compiler errors.
If you are looking to make a read-only table, you need to go through a bit of a complicated song and dance by overriding the ``__index`` metamethod. Here's a complete example on the way to do that using ``sol``:
.. code-block:: cpp
:caption: read-only.cpp
#define SOL_CHECK_ARGUMENTS
#include <sol.hpp>
#include <iostream>
struct object {
void my_func() {
std::cout << "hello\n";
}
};
int deny(lua_State* L) {
return luaL_error(L, "HAH! Deniiiiied!");
}
int main() {
sol::state lua;
lua.open_libraries(sol::lib::base);
object my_obj;
sol::table obj_table = lua.create_named_table("object");
sol::table obj_metatable = lua.create_table_with();
obj_metatable.set_function("my_func", &object::my_func, &my_obj);
// Set whatever else you need to
// on the obj_metatable,
// not on the obj_table itself!
// Properly self-index metatable to block things
obj_metatable[sol::meta_function::new_index] = deny;
obj_metatable[sol::meta_function::index] = obj_metatable;
// Set it on the actual table
obj_table[sol::metatable_key] = obj_metatable;
try {
lua.script(R"(
print(object.my_func)
object["my_func"] = 24
print(object.my_func)
)");
}
catch (const std::exception& e) {
std::cout << e.what() << std::endl;
}
return 0;
}
It is a verbose example, but it explains everything. Perhaps in the future ``sol2`` may feature a ``create_readonly_table`` abstraction for users!