lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


RJP Computing a écrit :
> On Thu, Jun 11, 2009 at 7:39 AM, steve donovan
> <steve.j.donovan@gmail.com <mailto: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.
> 
> 
> That is very cool! Thanks for sharing.
> -- 
> Regards,
> Ryan

alias lua = 'lua -lshell'
thanks, a great piece of code ;)