For the getting started guide, see Introduction to luajr.
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:
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 mymoduleThis 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:
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 and the Lua
manual.
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():
# Package module
mymod <- lua_module("Lua/mymodule.lua", package = "mypackage")and also declare any functions using lua_import():
#' 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:
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:
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:
.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().