2010-01-09 12 views
6

Je suis en train de développer une bibliothèque Lua dans laquelle je devais mettre en majuscule la première lettre d'une chaîne donnée. Par conséquent, j'ai créé la fonction suivante:"Étendre" la table "chaîne" - comment le faire? Est-ce même une bonne idée?

local capitalize = function(s) 
    return string.gsub (s, 
    "(%w)([%w]*)", 
    function (first, rest) 
     return string.upper(first) .. rest 
    end, 
    1) 
end 

Ce fut d'abord une fonction « interne », utilisé uniquement sur ma bibliothèque.

Maintenant, j'ai réalisé que mes utilisateurs voudront utiliser cette fonction dans certains cas.

Question 1 Je pense à l'extension de la table de chaînes, mais je ne sais pas comment procéder. Est-ce suffisant pour faire cela, ou y a-t-il une manière plus "orientée"?

string.capitalize = function(s) 
    ... etc etc (same code as above) 

Question 2 Je me demande si elle est même une bonne idée de chaîne monkey-patch. Dois-je fournir une fonction publique "capitaliser" à la place?

EDIT - Dans le cas où quelqu'un trouve cela à l'avenir, une fonction « tirer » beaucoup plus simple est affiché sur la page string recipes:

str = str:gsub("^%l", string.upper) 

Répondre

6

Je fais souvent des extensions de tables intégrées. Je le fais principalement quand je pense qu'il manque quelque chose de vraiment important. La capitalisation n'a pas fait ma liste "importante", mais quelque chose qui s'appelle string.split a, par exemple.

Quand je fais cela, je suivre une convention de programmation:

require 'stringutil' -- load extra stuff into string.* 
require 'osutil'  -- load extra stuff into os.* 

Vous avez l'idée.

L'autre chose que je fais quand je fais attention est vous assurer que je ne remplace pas quelque chose qui est pas déjà, de sorte que je suis l'avenir imperméabilisé:

function extend(tab, field, val) 
    if tab[field] == nil then 
    tab[field] = val 
    return val 
    elseif tab[field] ~= val then 
    error(string.format('Extension %s.%s failed: already occupied by %s', 
         nameof(tab), field, tostring(val))) 
    else 
    return val 
    end 
end 

La fonction nameof est comme ceci:

function nameof(val) 
    for name, v in pairs(_G) do if v == val then return name end end 
    return '?' 
end 

Note finale: quand je l'intention de partager le code avec les autres, je tendance à ne pas modifier les tables prédéfinies. Selon la Règle d'or, cet espace de noms est partagé par tout le monde, et si d'autres personnes utilisent mon code, ce n'est pas juste pour moi de saisir les champs que je veux dans la table string prédéfinie.

+0

Merci pour le partage. Je vais enfin suivre votre "note finale" et ne pas polluer les cordes avec mes propres fonctions - je pense avoir trouvé une meilleure solution. Mais vos notes pourraient être utiles à l'avenir. – kikito

2

La réponse à la question n ° 1 est « oui ». La réponse à la question 2 est "c'est une question de goût".