Formateo de Strings
Parte de la sección Object Oriented Programming del Journey de Lua de Coddy — lección 16 de 70.
Cuando imprimes un objeto directamente, Lua muestra algo poco útil como table: 0x55a...—simplemente una dirección de memoria. El metamétodo __tostring te permite definir exactamente qué cadena representa a tu objeto cuando se imprime o se convierte a texto.
En el patrón de clase, añades __tostring como una función en tu tabla de clase. Dado que la propia clase sirve como metatabla para las instancias, Lua encuentra y utiliza automáticamente esta función:
local Player = {}
Player.__index = Player
function Player:new(name, level)
local instance = {}
setmetatable(instance, self)
instance.name = name
instance.level = level
return instance
end
function Player:__tostring()
return "Player: " .. self.name .. " (Level " .. self.level .. ")"
endAhora, cuando imprimes una instancia de Player, Lua llama a tu método __tostring automáticamente:
local hero = Player:new("Luna", 5)
print(hero) -- Salida: Player: Luna (Nivel 5)Observa que __tostring utiliza la sintaxis de dos puntos y recibe self, lo que te da acceso a todos los datos de la instancia. La función debe devolver una cadena; puedes formatearla de la manera que tenga sentido para tu objeto, combinando cualquier atributo en una representación legible.
Desafío
Fácil¡Vamos a construir una clase Book que sepa cómo presentarse! Cuando imprimas un libro directamente, Lua mostrará una cadena con un formato agradable en lugar de una críptica dirección de memoria, todo gracias al metamétodo __tostring.
Organizarás tu código en dos archivos:
Book.lua: Define tu claseBookcon el patrón de prototipo estándar. Cada libro debe almacenar untitley unauthor. Incluye un constructor:new(title, author)e implementa el metamétodo__tostringpara que al imprimir un libro se muestre su información en un formato legible.main.lua: Requiere tu módulo Book, crea instancias de libros e imprímelas directamente para ver tu formateo de cadena personalizado en acción.
Tu método __tostring debe devolver una cadena en este formato exacto:
"[title]" by [author]Observa que el título está envuelto en comillas dobles dentro de la cadena de salida.
Recibirás cuatro entradas:
- Título del primer libro
- Autor del primer libro
- Título del segundo libro
- Autor del segundo libro
En tu archivo principal, crea dos libros usando las entradas proporcionadas e imprime cada libro directamente (no llamando a un método, simplemente print(book)). Cada libro debe aparecer en su propia línea.
Por ejemplo, si las entradas son The Hobbit, J.R.R. Tolkien, 1984, y George Orwell, la salida debería ser:
"The Hobbit" by J.R.R. Tolkien
"1984" by George OrwellRecuerda que __tostring debe devolver una cadena, y dado que tu tabla de clase sirve como metatabla para las instancias, Lua encontrará y usará automáticamente tu función __tostring cuando imprimas un libro.
Hoja de referencia
El metamétodo __tostring define cómo se representa un objeto como una cadena de texto cuando se imprime o se convierte a texto.
Sin __tostring, imprimir un objeto solo muestra su dirección de memoria:
print(someObject) -- Output: table: 0x55a...Añade __tostring como un método en tu clase para personalizar la representación de cadena:
local Player = {}
Player.__index = Player
function Player:new(name, level)
local instance = {}
setmetatable(instance, self)
instance.name = name
instance.level = level
return instance
end
function Player:__tostring()
return "Player: " .. self.name .. " (Level " .. self.level .. ")"
endCuando imprimes una instancia, Lua llama automáticamente a __tostring:
local hero = Player:new("Luna", 5)
print(hero) -- Output: Player: Luna (Level 5)Puntos clave:
- Usa la sintaxis de dos puntos (
:) para que el método recibaself - Debe devolver una cadena de texto
- Accede a los datos de la instancia a través de
self - Dado que la tabla de la clase sirve como metatabla, Lua encuentra
__tostringautomáticamente
Pruébalo tú mismo
-- Requerir el módulo Book
local Book = require('Book')
-- Leer las entradas
local title1 = io.read()
local author1 = io.read()
local title2 = io.read()
local author2 = io.read()
-- TODO: Crear dos instancias de libro usando Book:new()
-- TODO: Imprimir cada libro directamente (solo usa print(book))
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Object Oriented Programming
1El concepto de 'self'
Tablas con funciones'self' explícitoLa sintaxis de dos puntosPunto vs. dos puntosResumen - Punto en movimiento4Proyecto: Banco Digital
Configuración del proyectoMétodo de depósito2Patrón de prototipo de clase
El concepto de prototipoVinculación con __indexEl constructor :new()Inicialización de atributosInstancias independientesResumen - Fábrica de coches5Sobrecarga de operadores en POO
Sumar objetosRestar objetosConcatenar objetosComparar objetos (<, >)Resumen - Matemáticas de la billetera8Encapsulamiento
Convenciones de nomenclaturaClosures para privacidadAcceso mediante ClosuresTablas de solo lecturaLógica de validaciónResumen - Bóveda segura11Patrones de diseño (Lite)
Funciones FactoryTabla SingletonPatrón IteradorObserver (Listener)Resumen - Logger Factory3Estado y Comportamiento de los Objetos
Variables de InstanciaMétodos GetterMétodos SetterPropiedades CalculadasFormateo de StringsComprobaciones de IgualdadResumen - Calificación del Estudiante6Fundamentos de la herencia
Configuración de la herenciaHerencia de métodosExtender el constructorAñadir métodos hijosCompartido vs. ÚnicoResumen: Jerarquía de formas