ONLamp.com
oreilly.comSafari Books Online.Conferences.

advertisement


Introducing Lua
Pages: 1, 2, 3

Several special entries can go into a meta table. In this example, the most important one is __index. This entry contains a table or a function that Lua will consult if its associated table does not have a requested entry. Consider a meta table M whose __index entry is a table P. If M is the meta table for table T, whenever code requests an entry in T that does not exist, Lua will consult table P to see if it has the requested entry. P of course could have its own meta table data. Also, a table can be its own meta table, in which case entries such as __index will be in the table and will show up in table iterators, for example, but will otherwise behave in the same way.



Given this, the Lua programmer can now indulge in some actual object-oriented programming by providing a way to create "instances" of a Hello object. The base object looks like this:

Hello = {}
function Hello:sayhello()
    print("Hello "..self.Name)
end

Add a constructor, New, with:

function Hello:New(name)
    -- Create a new, empty table as in instance of the hello object
    local instance = {}

    -- Initialize the Name member
    instance.Name  = name

    -- Set the Hello object as the metatable and
    -- __index table of the instance.  This way 
    -- the Hello object is searched for any member 
    -- (typically methods) the instance doesn't have.
    setmetatable(instance,self)
    self.__index   = self

    -- Return the instance 
    return instance
end

fred = Hello:New("Fred");
fred:sayhello()

In this constructor, the Hello table is both the meta table and the __index table of the instance object. Even though the instance table does not have, for example, the sayhello function in it, Lua can find it through the auspices of the meta table's __index entry. Object-oriented programming cognoscenti will recognize this as a prototype-based object system similar to that of the Self and JavaScript languages.

In addition to the language itself, Lua comes with a set of runtime libraries. These libraries are also written in ANSI C and are generally linked with the Lua interpreter. As a result, there's no need to set PATH environment variables or to deliver ancillary files when deploying an application with Lua integrated.

Extending Lua

Lua is a powerful language that can express solutions to problems in a variety of domains. Yet Python, Ruby and Perl are also quite powerful in their way. Lua's primary advantage over other languages is its compact, efficient size. This size, and the ease of integrating and extending Lua into a particular programming problem is the reason Lua is worthy of examination.

Lua will probably be easy to integrate into a project build system because it's ANSI C code that requires little in the way of configuration and depends on no external libraries (beyond the C runtime library). It is likely that it will be possible to simply add the Lua interpreter code from the distribution directly into a pre-existing build system. A review of the Makefiles that come with Lua will reveal any useful configuration settings. It's easy to configure Lua for virtually any platform that supports ANSI C development.

An easy use for Lua in a program is to process a Lua file as configuration file and retrieve global values set by the Lua code to configure the behavior of the application.

Imagine a program that does some lengthy processing. The user needs to be able to set a maximum time that that processing should continue before being canceled if necessary. Call this value maxtime. Here's a function that represents a loadconfig function the program can call to process the user's configuration file:

#include <lua.h>
#include <lualib.h>

void loadconfig(char *file, int *maxtime)
{
    /* Start the lua library */
    lua_State *L = lua_open();

    /* We'll open the Math Library for them for calculations */
    lua_pushcfunction(L,luaopen_math);
    lua_pushstring(L,LUA_MATHLIBNAME);
    lua_call(L,1,0);

    /* Load and compile the file, the use lua_pcall to interpret it */
    if (luaL_loadfile(L,file) || lua_pcall(L,0,0,0))
      /* my_lua_error simply prints an error message and exits */
      my_lua_error(L,"cannot load file: %s",lua_tostring(L,-1));

    /* Get the Lua maxtime global variable onto the stack */
    lua_getglobal(L,"maxtime");

    /* Check that it is in fact, a number. The -1 indicates the
     * first stack position from the top of the stack. */
    if (!lua_isnumber(L,-1))
       my_lua_error(L,"maxtime should be a number\n");

    /* Take the value off the stack and keep it */
    *maxtime = (int)lua_tonumber(L,-1);

    /* And we're done */
    lua_close(L);
}

The user can use os.getenv to consult the HOSTNAME environment variable and set maxtime to values that are consistent with the use policies associated with given machines.

Pages: 1, 2, 3

Next Pagearrow





Sponsored by: