Wednesday, October 14, 2009
Lua's long strings
I'm back from mucking with R's project for now …
One of the things I had to do on “Project: DoogieHowser” was figure out which tables needed updating before the questionnaire could start, in an attempt to get the thing as standalone as possible (since as written, it's almost, but not quite separate from the old undocumented hugely overwrought PHP framework) and one of the ways to test my findings was to populate the database and try it out.
And in order to test it over and over again, I wrote the code in PHP (this was just before I start learning Lua):
$now = time(); $id = mysql_insert_id($conn); $query = "INSERT INTO program (" . "order_number," . "orderid," . "clientid," . "editable," . "purchasedate," . "reactive_date" . ") " . "VALUES (" . "'119195450271'," . "25278," . $id . "," . "1," . $now . "," . $now . ")"; $result = mysql_query($query,$conn); $pid = mysql_insert_id($conn);
… and what can I say, it's PHP. It's messy. It's nasty. It's got a pediliction for punctuation.
Now, one of the neatest features of Lua is the use of “long brackets”, which make the construction of huge strings trivial:
a_long_string = [[ `Twas brillig, and the slithy toves Did gyre and gimble in the wabe: All mimsy were the borogoves, And the mome raths outgrabe. "Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Beware the Jubjub bird, and shun The frumious Bandersnatch!" ]]
It's a brilliant solution to such a problem (and even neater, there's a
method for embedding such long strings within a long string). It even
extends to comments. In Lua, the line comment starts with a
--
:
-- frob the widget a few times, just to make sure for i=1,10 do frob(widget) end
But a longer block comment starts with --[[
and ends with
]]
:
--[[ We need to frob the widget multiple times, since the bitbucket sometimes get stuck and needs to be forced a few times to clear up the issue. Through empirical testing we found that frobbing the widget 10 times will always work, doesn't effect performance *all* that much, and much more importantly, will allow me to get at least two hours sleep under the desk before da boss comes in and starts screaming about deadlines ... ]] for i=1,10 do frob(widget) end
So, had I used Lua, the above code would probably look something like:
now = os.time() id = mysql.insert_id(conn) query = string.format([[ INSERT INTO program ( order_number, orderid, clientid, editable, purchasedate, reactive_date ) VALUES ( '119195450271', 25278, %s, 1, %d, %d )]],id,now,now) res = mysql.query(query,conn) pid = mysql.insert_id(conn)
Not much different, but I didn't have to build up that huge string piecemeal, and it was certainly easier to type up.
And now that I think about it, I don't think it would be all that much code to fill in an SQL template with variables:
function sql_template(sql,text,vars) local function cmd(tag) local word = string.sub(tag,2,-2) if type(vars[word] == "string" then return sql.escape(vars[word]) elseif type(vars[word] == "function" then return sql.escape(vars[word]()) else return sql.escape(tostring(var[word])) end end local s = string.gsub(text,"{%w+}",cmd) return s end query = sql_template(mysql,[[ INSERT INTO program ( order_number, orderid, clientid, editable, purchasedate, reactive_date ) VALUES ( '119195450271', 25278, {id} 1, {now}, {now} )]] , { id = mysql.insert_id(conn), now = os.time() });
Hmmm … I might have to see if I can do something like that in PHP; it would certainly help in “Project: Leaflet” …