2 votes

Comment rends-tu une variable de classe non modifiable ?

J'ai rencontré ce problème lors d'un test en ligne. J'ai cette classe :

class DocumentStore
  def initialize(capacity)
    @capacity = capacity;
    @documents = []
  end

  def get_documents
    return @documents
  end

  def add_document(document)
    raise 'Le stockage de documents est plein' if @documents.length >= @capacity
    @documents.push(document)
  end

  def inspect
    return "Stockage de documents : #{@documents.length}/#{@capacity}"
  end
end

Je veux renvoyer les données du stockage via get_documents, et empêcher l'utilisateur de les modifier/affecter via l'objet renvoyé, par exemple,

ds = DocumentStore.new(3)
ds.add_document("Doc1")

docs = ds.get_documents
docs.push("Doc2")

puts ds.inspect # cela devrait simplement imprimer ["Doc1"]

4voto

Johan Wentholt Points 2137

Ceci est simplement réalisé en appelant Object#freeze en combinaison avec Object#dup. freeze ne retourne pas une copie gelée, mais gèle plutôt self et retourne self. Cela signifie qu'à défaut de l'appel à dup, vous ne pouvez pas modifier le tableau à l'intérieur de la classe.

def get_documents
  return @documents.dup.freeze

Vous pourriez également choisir d'utiliser uniquement dup, renvoyant une copie superficielle. Cela permet à l'appelant de modifier le tableau sans affecter @documents.

def get_documents
  return @documents.dup

Note : Gardez à l'esprit qu'il ne devrait pas y avoir d'autre façon de récupérer le tableau. Ruby retourne toujours la dernière instruction effectuée par une méthode. Cela signifie que votre méthode DocumentStore#add_document retournera le résultat de @documents.push(document).

Array#push

Ajouter - Ajoute l(es) objet(s) donné(s) à la fin de ce tableau. Cette expression retourne le tableau lui-même, donc plusieurs ajouts peuvent être chaînés ensemble. Voir aussi #pop pour l'effet contraire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X