Lua.API behaviour (Lua v0.3.0)
View SourceDefines the Behaviour for defining a Lua API
To create a module that exports functions to the global scope
defmodule MyAPI do
use Lua.API
# Can be called via `print("hi")` in lua
deflua print(msg), do: IO.puts msg
endOptionally, you can provide a scope
defmodule SpecificAPI do
use Lua.API, scope: "namespace.domain"
# Can be called via `namespace.domain.foo(5)` in lua
deflua foo(v), do: v
endYou can access Lua state
defmodule State do
use Lua.API
deflua bar(name), state do
# Pull's the value of `number` out of state
val = Lua.get!(state, [:number])
2 * val
end
endRegular functions are not exported
defmodule SpecificAPI do
use Lua.API
# Won't be exposed
def baz(v), do: v
endInstalling an API
A Lua.API can provide an optional install/3 callback, which
can run arbitrary Lua code or change the Lua state in any way.
An install/3 callback takes a Lua.t/0 and should either return a
Lua script to be evaluated, a Lua.Chunk.t/0, or return a new Lua.t/0
defmodule WithInstall do
use Lua.API, scope: "install"
@impl Lua.API
def install(lua, _scope, _data) do
Lua.set!(lua, [:foo], "bar")
end
endIf you don't need to write Elixir, but want to execute some Lua
to setup global variables, modify state, or expose some additonal
APIs, you can simply return a Lua chunk directly using the c modifier
on Lua.sigil_LUA/2
defmodule WithLua do
use Lua.API, scope: "whoa"
import Lua
@impl Lua.API
def install(_lua, _scope, _data) do
~LUA[print("Hello at install time!")]c
end
endGuards
When doing use Lua.API, we also import the guards documented in this API.
This can be useful for having different function heads that match on encoded
values. E.g.
deflua say_type(value) when is_table(value), do: "table"
deflua say_type(value) when is_userdata(value), do: "table"Keep in mind that if you want to work with values passed to deflua functions,
they still need to be decoded first.
Summary
Functions
Defines a function that can be exposed in Lua through Lua.load_api/3
Is the value a reference to an Erlang / Elixir function?
Is the value a reference to a Lua function?
Is the value a reference to an Erlang / Elixir mfa?
Is the value a reference to a Lua table?
Is the value a reference to userdata?
Raises a runtime exception inside an API function, displaying contextual information about where the exception was raised.
Types
@type scope_def() :: [String.t()]
Callbacks
Functions
See deflua/3
Defines a function that can be exposed in Lua through Lua.load_api/3
deflua add_two(number) when is_number(number) do
number + 2
endAccessing state
Sometimes, you may want to access or modify the Lua environment in a deflua. This
can be done by using the following syntax
deflua get_value(key), state do
# Access the Lua environment
Lua.get!(lua, [key])
endTo modify and return new state, return a tuple
deflua set_value(key, value), state do
# Return nothing but modify the state
{[], Lua.set!(lua, [key])}
endUsing guards
Since deflua uses non-conventional syntax to receive the current state, make sure
you specifiy the when clause and guards first, e.g.
deflua set_int(key, value) when is_integer(value), state do
# Return nothing but modify the state
{[], Lua.set!(lua, [key])}
endSpecifyiing the when cluase and guards last will result in a confusing error message.
Variadic functions
Technically, all Lua functions are variadic, which means they can receive
a variable number of arguments. As a convenience, Lua applies your arguments to
deflua functions so that they can be written in idiomatic Elixir.
If you need to handle variadic arguments, annotate the function with the @variadic
module attribute.
@variadic true
deflua print(args) do
IO.puts(Enum.join(args, " "))
end@variadic behavior
When using the
@variadicattribute, note that it is per-function.Luawill reset this attribute after every function definition, so there is no need to manually reset it yourself
Is the value a reference to an Erlang / Elixir function?
Is the value a reference to a Lua function?
Is the value a reference to an Erlang / Elixir mfa?
Is the value a reference to a Lua table?
Is the value a reference to userdata?
Raises a runtime exception inside an API function, displaying contextual information about where the exception was raised.