Capturing Lua variable as a string

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Capturing Lua variable as a string

Lythoner LY
Hi All,

I am working on an interesting industrial automation application where I am proposing Lua to our customer as a configuration and scripting language.
I found Lua in search for better language with small runtime, easy to extend feature. I like Lua because it so simple to use, understand, very handy and compliments python on many places.
I need the community help to standardize my configuration stuffs which I am writing now.

We needed to provide a simple shell scripting capability to our user where they can read and write data to the device(industrial automation). We have the core layers developed in C# and I was able to call C# from Lua and Lua from C#. And also I can write & read the data with the device. Perfect. I also modified one window based IronPython User control to support Lua on .NET. For us, Lua would have a window based User control to allow user to read and write data. I did replaces "print" function Lua with my C# callable function, hence I could capture the "print" function output. For me, it is OK so for.

Now I needed a help on configuration.

function DEF_PARAM(v)
return v
end

DeviceParam1= DEF_PARAM
{
NAME     = "DeviceParam1",
TYPE     = INT
}


DeviceParam2= DEF_PARAM
{
NAME     = "DeviceParam2",
TYPE     = INT
}


DeviceParam3= DEF_PARAM
{
NAME     = "DeviceParam3",
TYPE     = INT
}

The above is the configuration I use. Like "DeviceParam1", I have tens of thousand configurations parameters. DEF_PARAM is an example function which just return the variable as it is. But we do some extra business logics inside. I have taken them out in this posting.

DeviceParam1 is used as a variable(a table instance). I need it like that. But I have defined one more property called "NAME" which is assigned to "DeviceParam1" string. The same is repeated for all variables. Instead I want the string equivalent of variables DeviceParam1, DeviceParam2, DeviceParam3 handled internally by Lua and assigned to  NAME property.

Here is example.

function DEF_PARAM(v)
-- do something here to set NAME property from v
-- v["NAME"] = ???? How do I get string equivalent of variable v
return v
end

DeviceParam1= DEF_PARAM
{
-- NAME     = "DeviceParam1", -- I have taken off the NAME assignment here
TYPE     = INT
}

DeviceParam2= DEF_PARAM
{
TYPE     = INT
}


DeviceParam3= DEF_PARAM
{
TYPE     = INT
}


In shell,

> print(DeviceParam3.NAME)
DeviceParam3

>print (type(DeviceParam3.NAME)
string

Regards,

Krish
Reply | Threaded
Open this post in threaded view
|

Re: Capturing Lua variable as a string

Julien Hamaide-2
Lythoner LY wrote:
> Hi All,
> 
> I am working on an interesting industrial automation application where I
> am proposing Lua to our customer as a configuration and scripting language.
> I found Lua in search for better language with small runtime, easy to
> extend feature. I like Lua because it so simple to use, understand, very
> handy and compliments python on many places.
> I need the community help to standardize my configuration stuffs which I
> am writing now.
> 
> We needed to provide a simple shell scripting capability to our user
> where they can read and write data to the device(industrial automation).
> We have the core layers developed in C# and I was able to call C# from
> Lua and Lua from C#. And also I can write & read the data with the
> device. Perfect. I also modified one window based IronPython User
> control to support Lua on .NET. For us, Lua would have a window based
> User control to allow user to read and write data. I did replaces
> "print" function Lua with my C# callable function, hence I could capture
> the "print" function output. For me, it is OK so for.
> 
> Now I needed a help on configuration.
> 
> function DEF_PARAM(v)
> return v
> end
> 
> DeviceParam1= DEF_PARAM
> {
> NAME     = "DeviceParam1",
> TYPE     = INT
> }
> 
> 
> DeviceParam2= DEF_PARAM
> {
> NAME     = "DeviceParam2",
> TYPE     = INT
> }
> 
> 
> DeviceParam3= DEF_PARAM
> {
> NAME     = "DeviceParam3",
> TYPE     = INT
> }
> 
> The above is the configuration I use. Like "DeviceParam1", I have tens
> of thousand configurations parameters. DEF_PARAM is an example function
> which just return the variable as it is. But we do some extra business
> logics inside. I have taken them out in this posting.
> 
> DeviceParam1 is used as a variable(a table instance). I need it like
> that. But I have defined one more property called "NAME" which is
> assigned to "DeviceParam1" string. The same is repeated for all
> variables. Instead I want the string equivalent of variables
> DeviceParam1, DeviceParam2, DeviceParam3 handled internally by Lua and
> assigned to  NAME property.
> 
> Here is example.
> 
> function DEF_PARAM(v)
> -- do something here to set NAME property from v
> -- v["NAME"] = ???? How do I get string equivalent of variable v
> return v
> end
> 
> DeviceParam1= DEF_PARAM
> {
> -- NAME     = "DeviceParam1", -- I have taken off the NAME assignment here
> TYPE     = INT
> }
> 
> DeviceParam2= DEF_PARAM
> {
> TYPE     = INT
> }
> 
> 
> DeviceParam3= DEF_PARAM
> {
> TYPE     = INT
> }
> 
> 
> In shell,
> 
>> print(DeviceParam3.NAME)
> DeviceParam3
> 
>>print (type(DeviceParam3.NAME)
> string
> 
> Regards,
> 
> Krish

if you have a limited number of type, you can define them as global
variable :

INT = "INT"
FLOAT = "FLOAT"

function DEF_PARAM(v)
   -- do something here to set NAME property from v
   -- v["NAME"] = ???? How do I get string equivalent of variable v
   return v
end

Just load this script before your definition file, and TYPE will
automatically contain the text.




-- 
--
Julien Hamaide
Engineering Coach
10Tacle Studios Belgium / Elsewhere Entertainment

Reply | Threaded
Open this post in threaded view
|

Re: Capturing Lua variable as a string

Luiz Henrique de Figueiredo
In reply to this post by Lythoner LY
> The same is repeated for all variables. Instead I want the string
> equivalent of variables DeviceParam1, DeviceParam2, DeviceParam3
> handled internally by Lua and assigned to NAME property.

Set up a proxy for _G and set a __newindex for the proxy that does that.
Something  like this:

    local function set(t,k,v)
	    print("SET",k,v,type(v))
	    if type(v)=="table" then v.NAME=k end
	    rawset(t,k,v)
    end
    setmetatable(getfenv(),{__index=_G,__newindex=set})

Reply | Threaded
Open this post in threaded view
|

Re: Capturing Lua variable as a string

Romulo Bahiense
In reply to this post by Julien Hamaide-2
Julien Hamaide wrote:
Lythoner LY wrote:
Hi All,

>> (snip)

if you have a limited number of type, you can define them as global
variable :

INT = "INT"
FLOAT = "FLOAT"

function DEF_PARAM(v)
   -- do something here to set NAME property from v
   -- v["NAME"] = ???? How do I get string equivalent of variable v
   return v
end

Just load this script before your definition file, and TYPE will
automatically contain the text.





I think he meant the name of the variable:


>> In shell,
>>
>>> print(DeviceParam3.NAME)
>> DeviceParam3
>>
>>> print (type(DeviceParam3.NAME)
>> string


Unfortunately, it is not possible to know what is the name of the variable you are assigning to (inside the DEF_PARAM function, of course). What I suggest, is to __newindex the chunk's environment and post-assign the name. Something like:


myconfiguration.lua:
DeviceParam1 = DEF_PARAM{ TYPE = INT }
DeviceParam2 = DEF_PARAM{ TYPE = INT }
DeviceParam3 = DEF_PARAM{ TYPE = INT }

~~ end of myconfiguration.lua:


configloader.lua
function load( filename )
    local f = assert( loadfile( filename ) )
    local e = setmetatable( {}, {
        __index = _G;
        __newindex = function( t, k, v )
            if type( k ) == 'string' and type( v ) == 'table' then
                v.NAME = k
            end
        end; } )
    setfenv( f, e )
    f()
end

~~ end of configloader.lua

Of course, this will cause all assignments of tables to global variables be changed. You can make some tricks to only assign the NAME fields to a particular subset. First, you can check for the presence of a TYPE attribute as a pre-condition (trivial). Second, you can store the newly created table in another table while creating it with DEF_PARAM and then check if the table being assigned belongs to it:

configloader2.lua
function load( filename )
    local f = assert( loadfile( filename ) )

    local t = {}
    local old_DEF_PARAM = DEF_PARAM

    local e = setmetatable(
        {
            DEF_PARAM = function( info )
                -- In case DEF_PARAM creates another table...
                info = old_DEF_PARAM( info )
                t[ info ] = true
                return info
            end;
        }, {
            __index = _G;
            __newindex = function( t, k, v )
                if t[ v ] then
                    v.NAME = k
                end
            end;
        }
    )
    setfenv( f, e )
    f()
end

~~ end of configloader2.lua

Hope that helps,

--rb

Reply | Threaded
Open this post in threaded view
|

Re: Capturing Lua variable as a string

Romulo Bahiense

Oops, one mistake:

configloader2.lua
function load( filename )
    local f = assert( loadfile( filename ) )

    local t = {}
    local old_DEF_PARAM = DEF_PARAM

    local e = setmetatable(
        {
            DEF_PARAM = function( info )
                -- In case DEF_PARAM creates another table...
                info = old_DEF_PARAM( info )
                t[ info ] = true
                return info
            end;
        }, {
            __index = _G;
            __newindex = function( self, k, v )
                if t[ v ] then
                    v.NAME = k
                end
            end;
        }
    )
    setfenv( f, e )
    f()
end

~~ end of configloader2.lua


I was also using a 't' as the name of 'self' on '__newindex'. Sorry.
--rb

Reply | Threaded
Open this post in threaded view
|

Re: Capturing Lua variable as a string

Lythoner LY
Hi Romulo Bahiense, Luiz, Gerald,  Julien,

It worked :-). Thanks a lot for your all help.

Regards,

Krish



Romulo Bahiense wrote:

Oops, one mistake:

configloader2.lua
function load( filename )
    local f = assert( loadfile( filename ) )

    local t = {}
    local old_DEF_PARAM = DEF_PARAM

    local e = setmetatable(
        {
            DEF_PARAM = function( info )
                -- In case DEF_PARAM creates another table...
                info = old_DEF_PARAM( info )
                t[ info ] = true
                return info
            end;
        }, {
            __index = _G;
            __newindex = function( self, k, v )
                if t[ v ] then
                    v.NAME = k
                end
            end;
        }
    )
    setfenv( f, e )
    f()
end

~~ end of configloader2.lua


I was also using a 't' as the name of 'self' on '__newindex'. Sorry.
--rb