Peter Shook

lua-users home
wiki

I'm a C/Awk/Perl hacker who wasn't very pleased with Perl's large list of obscure functions and macros know as XS. That and Perl's megaton size made me switch to Lua. Although Perl's extension tools and documentation have improved since I switched to Lua, I won't go back to Perl simply because Lua is truly a joy to use.

Sample Lua Code

Sample C++ Code

Sample C Code

Hex Numbers Patch [1]

Lua can handle hex numbers with the tonumber function, but my fellow engineers are more comfortable with C's 0x syntax so I made this patch for them.

This patch is for 5.0 but it is so simple, you can easily get it to work with older versions of Lua. lua-5.1-alpha version [2]

$ lua
Lua 5.0  Copyright (C) 1994-2003 Tecgraf, PUC-Rio
> = 0x10
16
> = 0x100
256
> function hex(n)
>>   return tonumber(n,16)
>> end
>
> = 0xff == hex'FF'
true
>

Read Directory Patch [3]

This patch adds chdir, opendir and stat to the os table. It works on Linux, Cygwin and Mingwin.

Ruby Like Syntactic Sugar

For those who dislike typing self.member all the time, here is a version of [lauxlib.c] that changes luaL_loadfile and luaL_loadbuffer to substitute @somename for self.somename and @somemethod(...) for self:somemethod(...).

You can also use # for comments.

List = setmetatable({}, {__index = table})
List.__index = List

function List:new(...) return setmetatable(arg, self) end
function List:push(x) @insert(x) return self end
function List:pop() return @remove() end
function List:shift() return @remove(1) end
function List:append(list)
  for _,elem in ipairs(list) do @insert(elem) end
  return self
end

function List:fun(a, b)
  @a = a
  @b = b
  return @n
end

x = List:new(1, 2, 5)
x:foreachi(print)
x:push(99)
print(x:concat', ')
print('fun', x:fun('one', 'two'), x:shift())
x:foreach(print)
Here is the output from the example above.
$ lua eg.lua
1       1
2       2
3       5
1, 2, 5, 99
fun     4       1
1       2
2       5
3       99
a       one
b       two
n       3 

Local by Default

Those with a Python or PHP background probably prefer variables within functions to be local by default. This is easily done in Lua 5.0 by using the newindex event to give functions a new environment when they are stored in the package.

For example:

local Pkg = {}

local function fixfuncs(env, name, value)
  rawset(env, name, value)
  if type(value)=='function' then
    print('newfunction', env, name, value)
    setfenv(value, setmetatable({}, {__index=env}))
  end
end

setfenv(1, setmetatable(Pkg, {__index=getfenv(), __newindex=fixfuncs}))

y = 0

function one(x)
  y = x
  return y
end

function two()
  Pkg.y = 99
  y = 2
  return y
end

local function three()
  y = 3
  return y
end

print(y, one(1), y, two(), y, three(), y)
The code above should output the following:
$ lua test1.lua
newfunction     table: 0xa0459f0        one     function: 0xa046ab8
newfunction     table: 0xa0459f0        two     function: 0xa0466d8
0       1       0       2       99      3       3
If you want to access variables in either the package or global scope, you'll have to prefix them with either Pkg. or _G.. The newindex event won't work on local functions, but if you're not a Perl programmer you probably don't care.

New Table and Funciton Patch [4]

What if you wanted to magically alter the function environments for local function too? Here is a dubious patch that adds newfunction and newtable events. The metamethod for the newfunction event is called whenever a function is created in an environment with a __newfunction key in its metatable.

We can rewrite the previous example like so:

local Pkg = {}

local function fixfuncs(env, f)
  print('newfunction', env, f)
  setfenv(f, setmetatable({}, {__index=env}))
end

setfenv(1, setmetatable(Pkg, {__index=getfenv(), __newfunction=fixfuncs}))

y = 0

function one(x)
  y = x
  return y
end

function two()
  Pkg.y = 99
  y = 2
  return y
end

local function three()
  y = 3
  return y
end

print(y, one(1), y, two(), y, three(), y)
Now even function three's y variable is local.
$ lua test2.lua
newfunction     table: 0xa0459f0        function: 0xa045fb0
newfunction     table: 0xa0459f0        function: 0xa046478
newfunction     table: 0xa0459f0        function: 0xa040730
0       1       0       2       99      3       99

Separate Methods Patch [5]

This patch changes the semantics of object:method() to use a new and separate self event instead of the usual index event. This lets you add some class to your tables, and still leaves the index event free for other uses.

local Pkg = {}

local function fixtable(env, t)
  print('newtable', env, t)
  setmetatable(t, {__self=table})
end

setfenv(1, setmetatable(Pkg, {__index=getfenv(), __newtable=fixtable}))

t = { 'one', 'two', 'three' }

print(t:concat'/', t:getn(), t:remove(1), t:remove(), t:getn())
Here is the output for this example:
$ lua test3.lua
newtable        table: 0xa0459f0        table: 0xa045f98
one/two/three   3       one     three   1

Lua for Coldfire 5282

Here is a tar file that compiles with m68k-elf-gcc [6]

The from patch [7]

Here is a patch to unpack named values from a table value so you can do things like this:

$ src/lua
Lua 5.1 (alpha)  Copyright (C) 1994-2005 Lua.org, PUC-Rio
> write from io
> format from string
>
> function printf(...) write(format(...)) end
>
> printf("I should have written this patch %d years ago\n", 2)
I should have written this patch 2 years ago
>

Here is a basic version of the patch that uses the existing keyword in instead of from [8]


RecentChanges · preferences
edit · history
Last edited November 25, 2020 3:15 am GMT (diff)