Frage

Dass ich das vergessen habe, hat mich ein paar Mal gebissen x = y sorgt in Ruby dafür, dass x auf dasselbe Objekt verweist wie y;Ich bin zu sehr an Sprachen gewöhnt, in denen es in Ruby-Begriffen bedeutet: x = y.dup.Wenn ich das vergesse, ändere ich mich versehentlich y wenn ich denke, dass es auf der rechten Seite der Aufgabe sicher ist.

Ich kann sehen, dass es sinnvoll wäre, einfach zu vermeiden x = y Aufgaben ohne besonderen Grund, aber das Gleiche kann auch an anderen Orten lauern, z

name = (person.last_name.blank? ? 'unknown' : person.last_name)

wo ein später name << title würde tatsächlich person.last_name ändern und nicht nur den Namen.

Wenn Ihnen das auch passiert ist, wie haben Sie gelernt, es zu vermeiden?Gibt es bestimmte Warnsignale oder Muster, auf die man achten sollte?Betrachten Sie jeden Auftrag, den Sie machen, mit Argwohn?Benutzt du .dup eine Menge?Ich weiß nicht, ob mir die Verwendung von Ruby jemals in Fleisch und Blut übergehen wird, daher wäre ich über nützliche Tipps willkommen.

War es hilfreich?

Lösung

Das mag in einer (im Wesentlichen zwingenden) Sprache wie Ruby unorthodox klingen, aber mein Rat ist:vermeiden Kollateralschäden indem Objekte überhaupt nicht aktualisiert werden (außer wenn dies unbedingt erforderlich ist);Erstellen Sie stattdessen neue.Sie zahlen ein wenig Leistung, erhalten aber Code, der klarer, kompakter, modularer und einfacher zu debuggen ist.

http://en.wikipedia.org/wiki/Functional_programming

Erstellen Sie in Ihrem Beispiel einfach eine neue Zeichenfolge mit einem neuen Namen:

complete_name = name + title

Andere Tipps

Nur eine Ergänzung zu toklands Antwort:

Der funktionale Ansatz besteht darauf Unveränderlichkeit - d.h.Es werden keine vorhandenen Objekte verändert, sondern ein neues erstellt, wann immer Sie das Original ändern möchten.Dies widerspricht in gewisser Weise dem objektorientierten Paradigma, das auch Ruby mit sich bringt (Objekte behalten intern ihren Zustand, der durch den Aufruf von Methoden geändert werden kann), sodass Sie ein wenig zwischen den beiden Ansätzen abwägen müssen (auf der anderen Seite profitieren wir davon). indem mehrere Paradigmen in einer einzigen Sprache leicht zugänglich sind).

Also, drei Dinge, die Sie vorerst im Hinterkopf behalten sollten:

  1. Erfahren Sie, was eine Aufgabe in Ruby ist:nichts anderes als ein Objekt zu benennen.Also, wenn du sagst y=x, Sie sagen nur: „Wir geben einen anderen Namen.“ y zu dem, was auch immer genannt wurde x".
  2. name << title mutiert Objekt aufgerufen name.
  3. name += title Nimmt Objekte mit Namen auf name Und title, verkettet sie zu ein anderer Objekt und weist diesen neuen Objektnamen zu name.Es mutiert nichts.

Ich bin auch auf eine solche Situation gestoßen und sie führte zu einem Fehler, den ich einen halben Tag lang herausfinden musste.Im Wesentlichen habe ich so etwas gemacht

hash = {....}
filename = object.file_name
hash.each |k, v| {file_name.gsub!(k, v) if file_name.include? k}

Dieser Code befand sich in einer Schleife und in der Schleife erwartete ich die Variable file_name wieder auf den ursprünglichen Wert gesetzt werden.Aber der object.file_name wurde während der Ausführung geändert file_name.gsub!.Es gibt zwei Möglichkeiten, dieses Problem zu lösen.Entweder ersetzen Sie die .gsub! mit anrufen file_name = file_name.gsub oder tun file_name = object.file_name.dup.Ich habe mich für die zweite Option entschieden.

Ich denke, wir sollten mit Methoden vorsichtig sein ! Und <<, da sie das ursprüngliche Objekt, auf das sie einwirken, verändern, insbesondere nach Aufgaben wie dieser.

Eine Methode sollte eine Variable nicht ändern (z. B.durch Verwendung des Shift-Operators), es sei denn, die Definition besagt, dass es sie ändern wird.

Also:Ändern Sie niemals ein Objekt in einer Methode, die es nicht entweder (a) erstellt oder (b) dokumentiert hat, dass sie es ändert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top