Menu
Coddy logo textTech

Concaténer des objets

Fait partie de la section Object Oriented Programming du Journey Lua de Coddy — leçon 28 sur 70.

L'opérateur .. en Lua concatène des chaînes de caractères, mais que se passe-t-il si vous voulez combiner un objet avec une chaîne ? La métaméthode __concat vous permet de définir exactement comment cela doit fonctionner.

Lorsque Lua rencontre a .. b et qu'un opérande possède une métaméthode __concat, il appelle cette fonction avec les deux valeurs. C'est utile lorsque vous voulez que des objets s'intègrent naturellement dans des expressions de chaînes de caractères.

local Name = {}
Name.__index = Name

function Name:new(first, last)
    local obj = {first = first, last = last}
    setmetatable(obj, Name)
    return obj
end

function Name.__concat(a, b)
    if type(a) == "string" then
        return a .. b.first .. " " .. b.last
    else
        return a.first .. " " .. a.last .. b
    end
end

Remarquez que la fonction vérifie quel opérande est la chaîne de caractères. Puisque .. peut être utilisé comme "Hello " .. obj ou obj .. "!", votre métaméthode devrait gérer les deux cas.

local person = Name:new("Ada", "Lovelace")

print("Dr. " .. person)      -- Résultat : Dr. Ada Lovelace
print(person .. " PhD")      -- Résultat : Ada Lovelace PhD

Comme les autres métaméthodes d'opérateurs, __concat utilise la syntaxe à points et reçoit les deux opérandes comme arguments. La différence principale par rapport aux métaméthodes arithmétiques est que vous travaillez généralement avec des types mixtes — votre objet et une chaîne de caractères.

challenge icon

Défi

Facile

Construisons une classe Title qui peut s'intégrer naturellement dans des expressions de chaînes de caractères en utilisant l'opérateur ... C'est utile lorsque vous souhaitez combiner des objets avec des chaînes de manière lisible et intuitive, comme l'ajout de titres honorifiques ou de suffixes au titre d'une personne.

Vous organiserez votre code sur deux fichiers :

  • Title.lua : Définissez votre classe Title avec un champ text qui stocke la chaîne du titre. Incluez un constructeur :new(text) et implémentez la métaméthode __concat. Votre métaméthode doit gérer les deux cas : lorsqu'une chaîne de caractères précède l'objet ("prefix" .. obj) et lorsqu'une chaîne de caractères le suit (obj .. "suffix"). Le résultat doit combiner la chaîne avec le texte du titre de manière appropriée.
  • main.lua : Importez votre module Title, créez une instance de titre et démontrez la concaténation dans les deux sens.

Vous recevrez trois entrées :

  1. Le texte du titre (par exemple, "Engineer")
  2. Une chaîne de préfixe à placer avant le titre (par exemple, "Senior ")
  3. Une chaîne de suffixe à placer après le titre (par exemple, " III")

Dans votre fichier principal, créez un Title avec le texte donné. Effectuez ensuite deux concaténations et affichez chaque résultat sur une ligne distincte :

  1. Concaténez la chaîne de préfixe avec l'objet titre
  2. Concaténez l'objet titre avec la chaîne de suffixe

Par exemple, si les entrées sont Engineer, Senior , et III, la sortie devrait être :

Senior Engineer
Engineer III

La première ligne montre le préfixe combiné avec le titre, et la deuxième ligne montre le titre combiné avec le suffixe. Votre métaméthode __concat rend ce mélange naturel de chaînes possible !

Aide-mémoire

La métaméthode __concat vous permet de définir un comportement personnalisé pour l'opérateur de concaténation .. lors de l'utilisation d'objets.

Lorsque Lua rencontre a .. b et qu'un opérande possède une métaméthode __concat, il appelle cette fonction avec les deux valeurs.

Implémentation de base

local MyClass = {}
MyClass.__index = MyClass

function MyClass:new(value)
    local obj = {value = value}
    setmetatable(obj, MyClass)
    return obj
end

function MyClass.__concat(a, b)
    if type(a) == "string" then
        return a .. b.value
    else
        return a.value .. b
    end
end

Gestion des deux ordres d'opérandes

Puisque .. peut être utilisé comme "string" .. obj ou obj .. "string", votre métaméthode doit vérifier quel opérande est la chaîne de caractères et gérer les deux cas :

function Name.__concat(a, b)
    if type(a) == "string" then
        return a .. b.first .. " " .. b.last
    else
        return a.first .. " " .. a.last .. b
    end
end

Exemple d'utilisation

local person = Name:new("Ada", "Lovelace")

print("Dr. " .. person)      -- Résultat : Dr. Ada Lovelace
print(person .. " PhD")      -- Résultat : Ada Lovelace PhD

Comme les autres métaméthodes d'opérateurs, __concat utilise la syntaxe avec point et reçoit les deux opérandes comme arguments.

Essayez vous-même

-- Lire les entrées
local titleText = io.read()
local prefix = io.read()
local suffix = io.read()

-- Charger le module Title
local Title = require('Title')

-- TODO : Créer une instance de Title avec le titleText donné

-- TODO : Concaténer le préfixe avec l'objet title et afficher le résultat

-- TODO : Concaténer l'objet title avec le suffixe et afficher le résultat
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Object Oriented Programming