lua-users home
lua-l archive

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

One nice feature of string.gsub is that you can provide a table as the
replacement, e.g.:
local apps = {browser='firefox', irc='xchat'}
print(("your web browser is <browser>."):gsub('<(.-)>', apps))
--> your web browser is firefox.

However, this system has an unfortunate limitation: the keys are
always strings. That means:
local params = {'file.c', 'file.o'}
print(("gcc %1 -o %2"):gsub('%%(%d+)', params))
--> gcc %1 -o %2

to make this work, you need to wrap the lookup:

print(("gcc %1 -o %2"):gsub('%%(%d+)',
    function(n) return params[tonumber(n)] end))
--> gcc file.c -o file.o

and then of course lookup of non-numeric keys would fail, so you'd
need to uglify that further:
print(("gcc %1 -o %2"):gsub('%%(%d+)',
    function(n) return params[tonumber(n) or n] end))

and if you wanted to remain compatible with the current behaviour...
print(("gcc %1 -o %2"):gsub('%%(%d+)',
    function(n) return params[tonumber(n)] or params[n] end))  --ugly!

I feel like this could be improved by having string.gsub try to
convert each key to a number, and keep it as a string only if that
fails. (To maintain compatibility it can also try as a string if it
doesn't find it as a number.) I imagine this is a fairly common use,

function replace_params(str, ...) return str:gsub('%%(%d+)', {...})
end --looks nice, but doesn't work!
print(replace_params('gcc %1 -o %2', 'file.c', 'file.o'))

Sent from my toaster.