Documentation
¶
Overview ¶
Package luar provides custom type reflection to gopher-lua.
Notice ¶
This package is currently in development, and its behavior may change. This message will be removed once the package is considered stable.
Basic types ¶
Go bool, number, and string types are converted to the equivalent basic Lua type.
Example:
New(L, "Hello World") -> lua.LString("Hello World")
New(L, uint(834)) -> lua.LNumber(uint(834))
Channel types ¶
Channel types have the following methods defined:
receive(): Receives data from the channel. Returns nil plus false if the
channel is closed.
send(data): Sends data to the channel.
close(): Closes the channel.
Taking the length (#) of a channel returns how many unread items are in its buffer.
Example:
ch := make(chan string)
L.SetGlobal("ch", New(L, ch))
---
ch:receive() -- equivalent to v, ok := ch
ch:send("hello") -- equivalent to ch <- "hello"
ch:close() -- equivalent to close(ch)
Function types ¶
Function types can be called from Lua. Its arguments and returned values will be automatically converted from and to Lua types, respectively (see exception below). However, a function that uses luar.LState can bypass the automatic argument and return value conversion (see luar.LState documentation for example).
Example:
fn := func(name string, age uint) string {
return fmt.Sprintf("Hello %s, age %d", name, age)
}
L.SetGlobal("fn", New(L, fn))
---
print(fn("Tim", 5)) -- prints "Hello Tim, age 5"
A special conversion case happens when function returns a lua.LValue slice. In that case, luar will automatically unpack the slice.
Example:
fn := func() []lua.LValue {
return []lua.LValue{lua.LString("Hello"), lua.LNumber(2.5)}
}
L.SetGlobal("fn", New(L, fn))
---
x, y = fn()
print(x) -- prints "Hello"
print(y) -- prints "2.5"
Map types ¶
Map types can be accessed and modified like a normal Lua table a meta table. Its length can also be queried using the # operator.
Rather than using pairs to create an map iterator, calling the value (e.g. map_variable()) will return an iterator for the map.
Example:
places := map[string]string{
"NA": "North America",
"EU": "European Union",
}
L.SetGlobal("places", New(L, places))
---
print(#places) -- prints "2"
print(places.NA) -- prints "North America"
print(places["EU"]) -- prints "European Union"
for k, v in places() do
print(k .. ": " .. v)
end
Slice types ¶
Like map types, slices be accessed, be modified, and have their length queried. Additionally, the following methods are defined for slices:
append(items...): Appends the items to the slice. Returns a slice with
the items appended.
capacity(): Returns the slice capacity.
For consistency with other Lua code, slices use one-based indexing.
Example:
letters := []string{"a", "e", "i"}
L.SetGlobal("letters", New(L, letters))
---
letters = letters:append("o", "u")
Struct types ¶
Struct types can have their fields accessed and modified and their methods called. First letters of field/method names are automatically converted to uppercase.
Example:
type Person {
Name string
}
func (p Person) SayHello() {
fmt.Printf("Hello, %s\n", p.Name)
}
tim := Person{"Tim"}
L.SetGlobal("tim", New(L, tim))
---
tim:SayHello() -- same as tim:sayHello()
Pointer types ¶
Pointers to structs operate the same way structs do. Pointers can also be dereferenced using the unary minus (-) operator.
Example:
str := "hello"
L.SetGlobal("strptr", New(L, &str))
---
print(-strptr) -- prints "hello"
The pointed to value can changed using the pow (^) operator.
Example:
str := "hello"
L.SetGlobal("strptr", New(L, &str))
---
print(str^"world") -- prints "world", and str's value is now "world"
Type types ¶
Type constructors can be created using NewType. When called, it returns a new variable which is of the same type that was passed to NewType. Its behavior is dependent on the kind of value passed, as described below:
Kind Constructor arguments Return value ----------------------------------------------------- Channel Buffer size (opt) Channel Map None Map Slice Length (opt), Capacity (opt) Slice Default None Pointer to the newly allocated value
Example:
type Person struct {
Name string
}
L.SetGlobal("Person", NewType(L, Person{}))
---
p = Person()
p.Name = "John"
print("Hello, " .. p.Name) // prints "Hello, John"
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func New ¶
func New(L *lua.LState, value interface{}) lua.LValue
New creates and returns a new lua.LValue for the given value.
The following types are supported:
Kind gopher-lua Type ------------------------------- nil LNil Bool LBool Int LNumber Int8 LNumber Int16 LNumber Int32 LNumber Int64 LNumber Uint LNumber Uint8 LNumber Uint32 LNumber Uint64 LNumber Float32 LNumber Float64 LNumber Complex64 *LUserData Complex128 *LUserData Array *LUserData Chan *LUserData Interface *LUserData Func *lua.LFunction Map *LUserData Ptr *LUserData Slice *LUserData String LString Struct *LUserData UnsafePointer *LUserData
func NewType ¶
func NewType(L *lua.LState, value interface{}) lua.LValue
NewType returns a new type creator for the given value's type.
When the lua.LValue is called, a new value will be created that is the same type as value's type.
Example ¶
L := lua.NewState()
defer L.Close()
type Song struct {
Title string
Artist string
}
L.SetGlobal("Song", luar.NewType(L, Song{}))
L.DoString(`
s = Song()
s.Title = "Montana"
s.Artist = "Tycho"
print(s.Artist .. " - " .. s.Title)
`)
Output: Tycho - Montana
Types ¶
type LState ¶
type LState struct {
*lua.LState
}
LState is an wrapper for gopher-lua's LState. It should be used when you wish to have a function/method with the standard "func(*lua.LState) int" signature.
Example ¶
const code = `
print(sum(1, 2, 3, 4, 5))
`
L := lua.NewState()
defer L.Close()
sum := func(L *luar.LState) int {
total := 0
for i := 1; i <= L.GetTop(); i++ {
total += L.CheckInt(i)
}
L.Push(lua.LNumber(total))
return 1
}
L.SetGlobal("sum", luar.New(L, sum))
if err := L.DoString(code); err != nil {
panic(err)
}
Output: 15
type Meta ¶
type Meta interface {
LuarCall(arguments ...interface{}) interface{}
LuarIndex(key interface{}) interface{}
LuarNewIndex(key, value interface{})
}
Meta can be implemented by a struct or struct pointer. Each method defines a fallback action for the corresponding Lua metamethod.
The signature of the methods does not matter; they will be converted using the standard function conversion rules. Also, a type is allowed to implement only a subset of the interface.
Example ¶
const code = `
proxy(234, nil, "asd", {})
`
L := lua.NewState()
defer L.Close()
// Proxy has the following method defined:
// func (p *Proxy) LuarCall(args ...lua.LValue) {
// fmt.Printf("I was called with %d arguments!\n", len(args))
// }
//
proxy := &Proxy{}
L.SetGlobal("proxy", luar.New(L, proxy))
if err := L.DoString(code); err != nil {
panic(err)
}
Output: I was called with 4 arguments!