---
title: "Lua modules"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Lua modules}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

*For the getting started guide, see [Introduction to `luajr`](luajr.html).*

## Introduction

This vignette shows you how to integrate Lua code into your R package, either 
for internal use within the package or for direct use by your package's users.

Generally when you want to include Lua code in your package, it means that you
want to include one or more functions written in Lua either internally in your 
package or as an outward-facing function for your users.

In Lua, the standard way to write a "module" -- Lua's equivalent of R's 
packages -- is to put together a Lua script that returns a Lua table, where the 
table contains all the functions (and variables) that the module should export. 
The script can also contain local functions or variables that are accessible 
only within the module itself. The module is then loaded with Lua's 
`require` function. For example, you may have a script `mymodule.lua` 
containing this Lua code:

```Lua
local mymodule = {}

mymodule.fave_name = "Nick"

function mymodule.greet(name)
    print("Hello, " .. name .. "!")
    if name == mymodule.fave_name then
        print("Incidentally, that's a great name. Nice one.")
    end
end

return mymodule
```

This script returns a Lua table containing the function `greet`, which in turn 
makes use of the module variable `fave_name`. In plain Lua, to use this module, 
you would write something like:

```Lua
local mymod = require "mymodule"
mymod.greet("Janet")
```

Here, Lua's `require` looks for a script called `mymodule.lua` in a few places,
including the current working directory. For more information on Lua modules, 
see the [Lua wiki](http://lua-users.org/wiki/ModulesTutorial) and the
[Lua manual](https://www.lua.org/manual/5.4/manual.html#pdf-require).

You can use a similar technique to load a Lua module into R using **luajr** as
follows. The recommendation is that you put `mymodule.lua` in your package 
directory under the subdirectory `inst/Lua`. Suppose your package is called
`"mypackage"` and your module file is `inst/Lua/mymodule.lua`. Then, somewhere 
in your R package scripts, declare the module using `lua_module()`:

```R
# Package module
mymod <- lua_module("Lua/mymodule.lua", package = "mypackage")
```

and also declare any functions using `lua_import()`:

```R
#' Greet the user
#' 
#' This function gives a cheerful greeting to the user.
#' 
#' @export
greet <- function(name) lua_import(mymod, "greet", "native")
```

You need to have this special function definition to expose the Lua function to
your package users and also to specify the argcode (see `lua_func()`) for the 
function. As shown, you can document and export the function as normal, e.g. 
with `roxygen2` syntax in the example above.

Note that `lua_import(...)` must be the only statement comprising the function
body. Within the call to `lua_import()`, we are supplying (1) the 
previously-declared module, (2) the name of the Lua function within the module, 
and (3) an argcode to define how the function parameters will be interpreted as 
Lua variables (see `lua_func()` for documentation on argcodes).

With the example above, the first time your package user calls `greet()`, the 
call to `lua_import()` will make sure the module is properly loaded and then 
will call the Lua function. It will also overwrite the existing body of 
`greet()` with a direct call to the Lua function so that subsequent calls to 
`greet()` execute as quickly as possible.

In some cases, you may want to do some processing or checking of function
arguments in R before calling the Lua function. You can do that with a
"two-step" process like this:

```R
greet0 <- function(name) lua_import(mymod, "greet", "native")
greet <- function(name) {
    if (!is.character(name)) {
        stop("greet expects a character string.")
    }
    greet0(name)
}
```

You can also manipulate non-function values within your module. For example,
if you wanted to change the "special" name recognized by `greet()`, you could
write in R:

```R
mymod["fave_name"] <- "Janet"
```

For more details, see the documentation for `lua_module()`.

Finally, a word on Lua states. By default, any module is automatically loaded 
into a newly-created Lua state that is specific to that module. There may be 
times when you wish to load the module into a specific state, such as the 
default `NULL` state or anything else. (See `lua_open()` for more details about
Lua states.)

To do this in your package, you need to assign this state to `mymod$L` after 
the module is declared but before any functions or variables from the module 
have been used. This is easy to do by using `.onLoad()`. Simply include in your 
package:

```R
.onLoad <- function(libname, pkgname)
{
    mymod$L <- NULL
}
```

This assigns `NULL` (i.e. the default Lua state shared with the user of your 
package) to the state used by the module, but you can also supply another
state, e.g. one opened by `lua_open()`.
