Bienvenidos sean a este post, hoy veremos el primero de dos ejemplos completos para ver como en la vida real se pone en practica todo lo visto hasta ahora, para el primer caso vamos a tomar como ejemplo el sitio web de Lua, la cual mantiene una base de datos que contiene unos ejemplos de proyectos alrededor del mundo que utilizan Lua, a cada entrada la representamos con un constructor en una forma auto-documentada, lo interesante de esta representacion es que un archivo con una secuencia de estas entradas es un programa de Lua 😲 la cual ejecuta una secuencia de llamadas para una funcion entry (por ejemplo), usando las tablas como argumentos, veamos su codigo:
entry{
title = "Tecgraf",
org = "Computer Graphics Technology Group, PUC-Rio",
url = "http://www.tecgraf.puc-rio.br/",
contact = "Waldemar Celes",
description = [[
Tecgraf is the result of a partnership between PUC-Rio,
the Pontifical Catholic University of Rio de Janeiro,
and <a HREF="http://www.petrobras.com.br>PETROBRAS</a>,
the Brazilian Oil company.
Tecgraf is Lua's birthplace, and the language has been
used there since 1993.
Currently, more than thirty programmers in Tecgraf use
LUA regularly, they hve written more than two hundred
thousand lines of code, distributed among dozens of
final products. ]]
}
Su composicion es bastante sencilla porque solamente contendra la informacion que mostraremos asignadas a unas variables, pero nuestra meta es mostrar esa informacion en una pagina de tipo web, y esta se transformara en la pagina http://www.lua.org/uses.html, como hay muchos proyectos la pagina final primero muestra un listado de los titulos de los mismos, y luego muestra los detalles del proyecto, veamos el codigo de un ejemplo de entrada:
<html>
<head><title>Projects using Lua</title></head>
<body bgcolor="#ffffff">
Hera are a brief descripction of some projects around the
world that use <a href="home.html">Lua</a>.<br>
<ul>
<li><a href="#1">Tecgraf</a>
<li> < ... otras entradas ... >
</ul>
<h3>
<a name="1" href="http://www.tecgraf.puc-rio.br/"Tecgraf</a>
<br>
<small><em>Computer Graphics Technology Group,
PUC-Rio</em></small>
</h3>
Tecgraf is the result of a partnership between PUC-Rio,
the Pontifical Catholic University of Rio de Janeiro,
and <a HREF="http://www.petrobras.com.br>PETROBRAS</a>,
the Brazilian Oil company.
Tecgraf is Lua's birthplace, and the language has been
used there since 1993.
Currently, more than thirty programmers in Tecgraf use
LUA regularly, they hve written more than two hundred
thousand lines of code, distributed among dozens of
final products.<p>
Contact: Waldemar Celes
<a name="2">< ... otras entradas ... ></a><hr>
< ... otras entradas ... >
</body></html>
Este es solo un ejemplo pero seria algo similar, si observamos se muestran algunos datos de los ingresados en entry, para leer esta informacion el programa simplemente utiliza una definicion correcta para entry y luego corre el archivo con los datos como un programa (con dofile), en este caso tendremos que atravesar todos los datos dos veces, primero por la lista de los titulos y luego por la descripcion de los proyectos, podriamos pensar primero en guardar todo en un array pero hay una opcion mejor que es correrlo cada vez con una definicion diferente de entry, para ello nuestro siguiente paso sera definir una funcion auxiliar que nos permita escribir texto formateado, lo vimos en este post, veamos el codigo:
function fwrite(fmt, ...)
return io.write(string.forma(fmt, ...))
end
Nuestra siguiente funcion sera writeheader la cual simplemente escribe el encabezado (header) de la pagina que sera siempre el mismo:
function writeheader()
io.write([[
<html>
<head><title>Projects using Lua</title></head>
<body bgcolor="#ffffff">
Hera are a brief descripction of some projects around the
world that use <a href="home.html">Lua</a>.<br>
]])
end
Reemplazando el encabezado del ejemplo de pagina web, la primera definicion de entry escribe cada titulo de proyecto como una lista de items, veamos el codigo:
function entry1(o)
contar = contar + 1
local titulo = o.title or '(sin titulo)'
fwrite('<li><a href="#%d">%s</a>\n', contar, titulo)
end
En este caso, el argumento o sera la tabla que describe el objeto, luego tendremos dos variables, una global y otra local, la global sera contar y se incrementara por cada entrada de la tabla, en cambio titulo sera de tipo local y almacenara el valor de la posicion title de la tabla o, si no hay ningun informado le asignara el valor «sin titulo», por ultimo la enviamos a fwrite, donde primero informaremos el texto a formatear, luego le pasaremos el valor de contar y titulo donde los asignara a %d y %s respectivamente, veamos el codigo para la segunda definicion:
function entry2(o)
contar = contar + 1
fwrite('<hr>\n<h3>\n')
local href = o.url and string.format('href="%s", o.url) or ''
local titulo = o.title or o.org or 'org'
fwrite('<a name="%d"%s>%s</a>\n, contar, href, titulo)
if o.title and o.org then
fwrite('<br><small><em>%s</em></small>, o.org)
end
fwrite('\n<h3>\n')
if o.description then
fwrite('%s<p>\n,
string.gsub(o.description, '\n\n+', '<p>\n'))
end
if o.email then
fwrite('Contact: <a href="mailto:%s">%s</a>\n',
o.email, o.contact or o.email)
elseif o.contact then
fwrite('Contact: %s\n', o.contact)
end
end
En este caso va a ser un poco mas compleja que la anterior pero por el simple hecho de que en este caso debemos tener en cuenta que algunas informaciones pueden estar omitidas, en esta situacion volveremos a incrementar a contar, luego imprimiremos un codigo HTML para crear el encabezado (o heading), crearemos dos variables locales llamadas href y titulo, en el primer caso le asignaremos el valor de o.url y luego lo formatearemos con string.format pero en caso de no existir el siguiente or lo asignara como vacio, no nil, en titulo le asignaremos el valor de o.title, sino existe el valor de org, y si tampoco existe le asigna la palabra org, con estos dos datos, al igual que antes enviaremos a fwrite, el valor de contar, href y titulo para que lo formatee correctamente, despues tendremos un condicional donde si existe o.title y o.org enviaremos a fwrite para que muestre el valor de o.org, una vez pasado el condicional cerraremos el encabezado, luego tendremos un condicional donde verifica que exista un valor asignado a o.description, en caso de existir lo envia a fwrite y lo procesa de lo contrario lo ignora y lo omite, nuestro siguiente condicional es con el o.email, en caso de existir mandamos a fwrite para crear un link para enviar un email, primero pasaremos la direccion de correo (o.email) y luego el de contacto y si no existe nuevamente el de correo para mostrarlo en pantalla pero en caso de que no exista u o.email sea nil, usamos un elseif donde verifica si existe o.contact y en caso de ser cierto lo envia a fwrite.
Como pueden ver esta funcion es un poco mas compleja pero no tan dificil, nuestra ultima funcion para agregar es writetail, veamos su codigo:
function writetail()
fwrite('</body></html>\n')
end
Como pueden observar simplemente es para cerrar nuestra pagina web, veamos el codigo final de nuestro programa:
db.lua
entry{
title = "Tecgraf",
org = "Computer Graphics Technology Group, PUC-Rio",
url = "http://www.tecgraf.puc-rio.br/",
contact = "Waldemar Celes",
description = [[
Tecgraf is the result of a partnership between PUC-Rio,
the Pontifical Catholic University of Rio de Janeiro,
and <a HREF="http://www.petrobras.com.br>PETROBRAS</a>,
the Brazilian Oil company.
Tecgraf is Lua's birthplace, and the language has been
used there since 1993.
Currently, more than thirty programmers in Tecgraf use
LUA regularly, they hve written more than two hundred
thousand lines of code, distributed among dozens of
final products. ]]
}
main.lua
function fwrite(fmt, ...)
return io.write(string.forma(fmt, ...))
end
function writeheader()
io.write([[
<html>
<head><title>Projects using Lua</title></head>
<body bgcolor="#ffffff">
Hera are a brief descripction of some projects around the
world that use <a href="home.html">Lua</a>.<br>
]])
end
function writeheader()
io.write([[
<html>
<head><title>Projects using Lua</title></head>
<body bgcolor="#ffffff">
Hera are a brief descripction of some projects around the
world that use <a href="home.html">Lua</a>.<br>
]])
end
function entry1(o)
contar = contar + 1
local titulo = o.title or '(sin titulo)'
fwrite('<li><a href="#%d">%s</a>\n', contar, titulo)
end
function entry2(o)
contar = contar + 1
fwrite('<hr>\n<h3>\n')
local href = o.url and string.format('href="%s", o.url) or ''
local titulo = o.title or o.org or 'org'
fwrite('<a name="%d"%s>%s</a>\n, contar, href, titulo)
if o.title and o.org then
fwrite('<br><small><em>%s</em></small>, o.org)
end
fwrite('\n<h3>\n')
if o.description then
fwrite('%s<p>\n,
string.gsub(o.description, '\n\n+', '<p>\n'))
end
if o.email then
fwrite('Contact: <a href="mailto:%s">%s</a>\n',
o.email, o.contact or o.email)
elseif o.contact then
fwrite('Contact: %s\n', o.contact)
end
end
function writetail()
fwrite('</body></html>\n')
end
local entrada = "db.lua"
writeheader()
contar = 0
f = loadfile(entrada)
entry = entry1
fwrite('<ul>\n')
f()
fwrite('</ul>\n')
contar = 0
entry = entry2
f()
writetail()
Observen como en nuestro programa tendremos todas las funciones una vez definidas, crearemos una variable local llamada entrada a la cual le asignaremos el valor de nuestro archivo con las entradas, db.lua, luego llamamos a la funcion writeheader para crear el encabezado de la pagina, seteamos a contar con el valor de 0, recuerden que debe ser global, creamos a f y le cargamos el archivo de entradas con loadfile, luego a entry le asignaremos la funcion entry1, llamamos a fwrite para crear el listado de titulos, usamos a f, que en realidad llama a entry1 para crear el listado, una vez terminado llamamos nuevamente a fwrite para cerrar el listado, en el siguiente paso reseteamos nuevamente a contar, ahora a entry le asignamos a entry2 y llamamos nuevamente a f para que nos muestre todos los datos restantes, por utimo llamamos a writetail para que cierre la pagina.
En resumen, hoy hemos visto un ejemplo en la vida real de todo lo visto hasta ahora, ya sean variables globales, locales, funciones, funciones con multiples argumentos, con escritura formateada, espero les haya sido util sigueme en Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Tambien podes donar
Es para mantenimiento del sitio, gracias!
$1.50