Shopify / go-lua

A Lua VM in Go
MIT License
3.15k stars 191 forks source link

Global Variable of type Lua Table #129

Open WillianBR opened 1 year ago

WillianBR commented 1 year ago

I'm sorry for bothering you guys, but I'm have hard time trying to create a global variable on go-lua of type table.

I'd not any issue to return a table from a function call (GO Lang internal func, returning a table type variable.).

But my litle tool need to create a global variable of type table with system information fields.

And it would be nice if I was able to set it as read-only. Using pure LUA, I can set a metatable, but I never did such thing using API (On this case GO code).

The part of expose a GO Lang function to LUA script and return a table as result was prety easy!

Does anybody did something like that?


For those who need return tables from GO function to Lua script, below is my code! I hope it help!

Example:

// Exposed functions table
var goFuncsTable = []lua.RegistryFunction{
    {"AppEnvironment", func(l *lua.State) int { return go_exposedLuaFunction(l) } },
}

// Register functions 
func UtilOpen(l *lua.State) int {
    lua.NewLibrary(l, goFuncsTable)
    return 1
}

// Function implementation itself
func go_exposedLuaFunction(l *lua.State) int {

    l.CreateTable(0, 6)

    l.PushString("1.0.0")
    l.SetField(-2, "Version")

    l.PushString(BuildDate)
    l.SetField(-2, "BuildDate")

    l.PushString(BuildTime)
    l.SetField(-2, "BuildTime")

    l.PushString(runtime.GOOS)
    l.SetField(-2, "OS")

    l.PushString(runtime.GOARCH)
    l.SetField(-2, "Arch")

    l.PushInteger(runtime.GOMAXPROCS(0))
    l.SetField(-2, "CPUCores")

    return 1 // Returning one single table
}
WillianBR commented 1 year ago

Table Manipulation

Hi Guys,

Since a post my issue, I had take some time to cool down and after that a deep reading.

After good reading of "Programming In Lua 2nd Edition", I find out the solution. The chapter 26 "Extending Your Application", into item "26.2 Table Manipulation", the provided sample about color table solve it.

To demonstrate how it works on GO-Lua, I'll show a small and dummies code here! As I did some test, I'll implement a more sofisticate function today, to solve my problem and after that publish it here! After all "Knowledge shared it's knowledge preserved and extended!".

Basic dummies sample code:

    l.NewTable()
    l.SetGlobal("System")
    l.Global("System")
    if l.IsTable(-1) {
        l.PushString("dirWatchar system to watch directories for changes.")
        l.SetField(-2, "Description")

        l.PushString("dirWatchar.exe")
        l.SetField(-2, "Executable")

        l.PushString(user.Name)
        l.SetField(-2, "UserName")

        l.PushString(user.HomeDir)
        l.SetField(-2, "UserHomeDir")

    } else {
        log.Println("Failed to create global variable System, type table.")
    }

After that we can safely use into LUA Script the code down bellow:

-- Prove of concept!
print( string.rep("-", 79))
print("SYSTEM:")
-- Show our table fields and values
DumpTable(System)
print( string.rep("-", 79))

-- Dump table code
function DumpTable(o)
  -- https://onelinerhub.com/lua/how-to-print-table
  if type(o) == 'table' then
    print("DBG> Table")
     for k,v in pairs(o) do
        print("DBG> ", k,": ", v)
     end
  else
     return tostring(o)
  end
end

My output was something like:

----------------------------------------------------------------
SYSTEM:
DBG> Table
DBG>    Description     :       dirWatchar system to watch directories for changes.
DBG>    Executable      :       dirWatchar.exe
  ...  ...  ...  ...  ...  ...  ...  ...  ...  ...  ...
----------------------------------------------------------------

I believe thats solve my own problem and after I have it implemented into my own code the code will be shared here.

Recommended read!

That's All Folks!