luar

package module
v1.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 2, 2019 License: MPL-2.0 Imports: 6 Imported by: 0

README

gopher-luar GoDoc

gopher-luar simplifies data passing to and from gopher-lua.

Example usage:

package luar_test

import (
	"fmt"

	"github.com/yuin/gopher-lua"
	"layeh.com/gopher-luar"
)

type User struct {
	Name  string
	token string
}

func (u *User) SetToken(t string) {
	u.token = t
}

func (u *User) Token() string {
	return u.token
}

const script = `
print("Hello from Lua, " .. u.Name .. "!")
u:SetToken("12345")
`

func Example_basic() {
	L := lua.NewState()
	defer L.Close()

	u := &User{
		Name: "Tim",
	}
	L.SetGlobal("u", luar.New(L, u))
	if err := L.DoString(script); err != nil {
		panic(err)
	}

	fmt.Println("Lua set your token to:", u.Token())
	// Output:
	// Hello from Lua, Tim!
	// Lua set your token to: 12345
}

License

MPL 2.0

Author

Tim Cooper (tim.cooper@layeh.com)

Documentation

Overview

Package luar simplifies data passing to and from gopher-lua. (https://github.com/yuin/gopher-lua).

Go to Lua conversions

See documentation of New function.

Lua to Go conversions

Lua types are automatically converted to match the output Go type (e.g. setting a struct field from Lua).

lua.LNil can be converted to any channel, func, interface, map, pointer, slice, unsafepointer, or uintptr value.

lua.LBool values are converted to bool.

lua.LNumber values are converted to float64.

lua.LString values are converted to string.

lua.LChannel values are converted to lua.LChannel.

*lua.LTable values can be converted to an array, slice, map, struct, or struct pointer. If the table is being assigned with no type information (i.e. to an interface{}), the converted value will have the type map[interface{}]interface{}.

The Value field of *lua.LUserData values are converted rather than the *lua.LUserData value itself.

*lua.LState values are converted to *lua.LState.

*lua.LFunction values are converted to Go functions. If the function is being assigned with no type information (i.e. to a interface{}), the function will have the signature func(...interface{}) []interface{}. The arguments and return values will be converted using the standard luar conversion rules.

Thread safety

This package accesses and modifies the Lua state's registry. This happens when functions like New are called, and potentially when luar-created values are used. It is your responsibility to ensure that concurrent access of the state's registry does not happen.

Example (Basic)
package main

import (
	"fmt"

	"github.com/yuin/gopher-lua"
	"layeh.com/gopher-luar"
)

type User struct {
	Name  string
	token string
}

func (u *User) SetToken(t string) {
	u.token = t
}

func (u *User) Token() string {
	return u.token
}

const script = `
    print("Hello from Lua, " .. u.Name .. "!")
    u:SetToken("12345")
    `

func main() {
	L := lua.NewState()
	defer L.Close()

	u := &User{
		Name: "Tim",
	}
	L.SetGlobal("u", luar.New(L, u))
	if err := L.DoString(script); err != nil {
		panic(err)
	}

	fmt.Println("Lua set your token to:", u.Token())
}
Output:

Hello from Lua, Tim!
Lua set your token to: 12345

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. Values are converted in the following manner:

A nil value (untyped, or a nil channel, function, map, pointer, or slice) is converted to lua.LNil.

A lua.LValue value is returned without conversion.

Boolean values are converted to lua.LBool.

String values are converted to lua.LString.

Real numeric values (ints, uints, and floats) are converted to lua.LNumber.

Functions are converted to *lua.LFunction. When called from Lua, Lua values are converted to Go using the rules described in the package documentation, and Go return values converted to Lua values using the rules described by New.

If a function has the signature:

func(*LState) int // *LState defined in this package, not in lua

The argument and return value conversions described above are skipped, and the function is called with the arguments passed on the Lua stack. Return values are pushed to the stack and the number of return values is returned from the function.

Arrays, channels, maps, pointers, slices, and structs are all converted to *lua.LUserData with its Value field set to value. The userdata's metatable is set to a table generated for value's type. The type's method set is callable from the Lua type. If the type implements the fmt.Stringer interface, that method will be used when the value is passed to the Lua tostring function.

With arrays, the # operator returns the array's length. Array elements can be accessed with the index operator (array[index]). Calling an array (array()) returns an iterator over the array that can be used in a for loop. Two arrays of the same type can be compared for equality. Additionally, a pointer to an array allows the array elements to be modified (array[index] = value).

With channels, the # operator returns the number of elements buffered in the channel. Two channels of the same type can be compared for equality (i.e. if they were created with the same make call). Calling a channel value with no arguments reads one element from the channel, returning the value and a boolean indicating if the channel is closed. Calling a channel value with one argument sends the argument to the channel. The channel's unary minus operator closes the channel (_ = -channel).

With maps, the # operator returns the number of elements in the map. Map elements can be accessed using the index operator (map[key]) and also set (map[key] = value). Calling a map value returns an iterator over the map that can be used in a for loop. If a map's key type is string, map values take priority over methods.

With slices, the # operator returns the length of the slice. Slice elements can be accessed using the index operator (slice[index]) and also set (slice[index] = value). Calling a slice returns an iterator over its elements that can be used in a for loop. Elements can be appended to a slice using the add operator (new_slice = slice + element).

With structs, fields can be accessed using the index operator (struct[field]). As a special case, accessing field that is an array or struct field will return a pointer to that value. Structs of the same type can be tested for equality. Additionally, a pointer to a struct can have its fields set (struct[field] = value).

Struct field accessibility can be changed by setting the field's luar tag. If the tag is empty (default), the field is accessed by its name and its name with a lowercase first letter (e.g. "Field1" would be accessible using "Field1" or "field1"). If the tag is "-", the field will not be accessible. Any other tag value makes the field accessible through that name.

Pointer values can be compared for equality. The pointed to value can be changed using the pow operator (pointer = pointer ^ value). A pointer can be dereferenced using the unary minus operator (value = -pointer).

All other values (complex numbers, unsafepointer, uintptr) are converted to *lua.LUserData with its Value field set to value and no custom metatable.

func NewType

func NewType(L *lua.LState, value interface{}) lua.LValue

NewType returns a new type generator for the given value's type.

When the returned lua.LValue is called, a new value will be created that is dependent on value's type:

If value is a channel, the first argument optionally specifies the channel's buffer size (defaults to 1). The new channel is returned.

If value is a map, a new map is returned.

If value is a slice, the first argument optionally specifies the slices's length (defaults to 0), and the second argument optionally specifies the slice's capacity (defaults to the first argument). The new slice is returned.

All other types return a new pointer to the zero value of value's type.

Example
L := lua.NewState()
defer L.Close()

type Song struct {
	Title  string
	Artist string
}

L.SetGlobal("Song", NewType(L, Song{}))
if err := L.DoString(`
		s = Song()
		s.Title = "Montana"
		s.Artist = "Tycho"
		print(s.Artist .. " - " .. s.Title)
	`); err != nil {
	panic(err)
}
Output:

Tycho - Montana

Types

type Config

type Config struct {
	// The name generating function that defines under which names Go
	// struct fields will be accessed.
	//
	// If nil, the default behaviour is used:
	//   - if the "luar" tag of the field is "", the field name and its name
	//     with a lowercase first letter is returned
	//  - if the tag is "-", no name is returned (i.e. the field is not
	//    accessible)
	//  - for any other tag value, that value is returned
	FieldNames func(s reflect.Type, f reflect.StructField) []string

	// The name generating function that defines under which names Go
	// methods will be accessed.
	//
	// If nil, the default behaviour is used:
	//   - the method name and its name with a lowercase first letter
	MethodNames func(t reflect.Type, m reflect.Method) []string
	// contains filtered or unexported fields
}

Config is used to define luar behaviour for a particular *lua.LState.

func GetConfig

func GetConfig(L *lua.LState) *Config

GetConfig returns the luar configuration options for the given *lua.LState.

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 *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", New(L, sum))

if err := L.DoString(code); err != nil {
	panic(err)
}
Output:

15

type Metatable

type Metatable struct {
	*lua.LTable
}

Metatable is the Lua metatable for a Go type.

func MT

func MT(L *lua.LState, value interface{}) *Metatable

MT returns the metatable for value's type. nil is returned if value's type does not use a custom metatable.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL