On Thu, Jun 11, 2009 at 7:39 AM, steve donovan
<steve.j.donovan@gmail.com> wrote:
Here's another little example of how metamethods can do interesting
things, so that what appears to be a function actually translates into
a shell command.
The idea is to write the shell commands in a natural Lua way:
print(shell.which 'lua')
print(shell.chmod('+x','test3.lua'))
print(shell.gcc ({'-shared','-fpic'},'test 3.lua'))
and then use __index on the shell table to do the translation. This
could be called the 'shell pattern' for lack of a better term.
-- shell.lua
shell = {}
local mt = {}
setmetatable(shell,mt)
function shell.command(cmd,no_lf)
print(cmd)
local f = io.popen(cmd..' 2>&1; echo "-retcode:$?"' ,'r')
local l = f:read '*a'
f:close()
local i1,i2,ret = l:find('%-retcode:(%d+)\n$')
if no_lf and i1 > 1 then i1 = i1 - 1 end
l = l:sub(1,i1-1)
return tonumber(ret),l
end
local concat
concat = function (args)
for i,s in ipairs(args) do
if type(s) == 'table' then
args[i] = concat(s)
else
args[i] = s:find '%s' and '"'..s..'"' or s
end
end
return table.concat(args,' ')
end
function mt.__index(t,k)
return function(...)
return shell.command(k..' '..concat{...},true)
end
end
print(shell.which 'lua')
print(shell.chmod('+x','test3.lua'))
print(shell.gcc ({'-shared','-fpic'},'test 3.lua'))
------
And the output is:
which lua
0 /usr/local/bin/lua
chmod +x test3.lua
0
gcc -shared -fpic "test 3.lua"
1 gcc: test 3.lua: No such file or directory
gcc: no input files
Ignore the particular implementation of shell.command, which can be
more elegantly done with luaex.
A subpattern here is a generalization of concat to handle nested
tables, which makes it easy to compose command lines.
For example, to compile simple Lua extensions:
local liboptions = {'-shared','-fpic'}
local includes = {'-I','/home/sdonovan/lua/include'}
function lcompile(name)
local status = shell.gcc(liboptions,includes,name..'.c','-o',name..'.so')
return status == 0
end
steve d.