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
end
Optionally, 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
end
You 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
end
Regular functions are not exported
defmodule SpecificAPI do
use Lua.API
# Won't be exposed
def baz(v), do: v
end
Installing 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
end
If 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
end
Guards
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
end
Accessing 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])
end
To 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])}
end
Using 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])}
end
Specifyiing 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
@variadic
attribute, note that it is per-function.Lua
will 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.