This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.
The fourth edition targets Lua 5.3 and is available at Amazon and other bookstores.
By buying the book, you also help to support the Lua project.

27.3.2 – References

You should never use numbers as keys in the registry, because such keys are reserved for the reference system. This system is composed by a couple of functions in the auxiliary library that allow you to store values in the registry without worrying about how to create unique names. (Actually, those functions can act on any table, but they are typically used with the registry.)

The call

    int r = luaL_ref(L, LUA_REGISTRYINDEX);
pops a value from the stack, stores it into the registry with a fresh integer key, and returns that key. We call this key a reference.

As the name implies, we use references mainly when we need to store a reference to a Lua value inside a C structure. As we have seen, we should never store pointers to Lua strings outside the C function that retrieved them. Moreover, Lua does not even offer pointers to other objects, such as tables or functions. So, we cannot refer to Lua objects through pointers. Instead, when we need such pointers, we create a reference and store it in C.

To push the value associated with a reference r onto the stack, we simply write

    lua_rawgeti(L, LUA_REGISTRYINDEX, r);
Finally, to release both the value and the reference, we call
    luaL_unref(L, LUA_REGISTRYINDEX, r);
After this call, luaL_ref may return the value in r again as a new reference.

The reference system treats nil as a special case. Whenever you call luaL_ref for a nil value, it does not create a new reference, but instead returns the constant reference LUA_REFNIL. The call

has no effect, whereas
pushes a nil, as expected.

The reference system also defines the constant LUA_NOREF, which is an integer different from any valid reference. It is useful to mark references as invalid. As with LUA_REFNIL, any attempt to retrieve LUA_NOREF returns nil and any attempt to release it has no effect.