3 Stimmen

Was ist die bewährte Praxis in Ruby, um einen Missbrauch der Zuweisung "=" zu vermeiden?

Ich wurde schon ein paar Mal gebissen, weil ich vergessen habe, dass x = y in Ruby dazu führt, dass x auf dasselbe Objekt wie y verweist; Ich bin zu sehr an Sprachen gewöhnt, in denen es in Ruby-Terminen bedeutet, x = y.dup. Wenn ich das vergesse, ändere ich versehentlich y, wenn ich denke, dass es auf der rechten Seite der Zuweisung sicher ist.

Ich kann sehen, dass es sinnvoll wäre, einfache x = y Zuweisungen ohne speziellen Grund zu vermeiden, aber das Gleiche kann auch an anderen Stellen lauern, wie zum Beispiel

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

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

Wenn Ihnen das auch passiert ist, wie haben Sie gelernt, es zu vermeiden? Gibt es bestimmte rote Flaggen oder Muster, auf die Sie achten sollten? Sehen Sie mit Argwohn jede Zuweisung, die Sie machen? Verwenden Sie viel .dup? Ich weiß nicht, ob Rubys Verwendung jemals für mich zur Gewohnheit wird, also wären alle nützlichen Tipps willkommen.

5voto

tokland Punkte 63238

Dies mag in einer (im Wesentlichen imperativen) Sprache wie Ruby unkonventionell klingen, aber mein Rat ist: Vermeiden Sie Nebenwirkungen, indem Sie Objekte überhaupt nicht aktualisieren (außer wenn es unbedingt erforderlich ist); erstellen Sie stattdessen neue. Sie zahlen etwas an Leistung ein, aber Sie erhalten Code, der klarer, kompakter, modularer und einfacher zu debuggen ist.

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

Also, erstellen Sie in Ihrem Beispiel einfach einen neuen String mit einem neuen Namen:

complete_name = name + title

1voto

Mladen Jablanović Punkte 42360

Nur eine Ergänzung zur Antwort von tokland:

Der funktionale Ansatz besteht auf Unveränderlichkeit - d.h. bestehende Objekte nicht zu verändern, sondern immer ein neues Objekt zu erstellen, wenn Änderungen am Original vorgenommen werden sollen. Dies steht ein wenig im Widerspruch zum objektorientierten Paradigma, das auch von Ruby eingeführt wird (Objekte behalten ihren Zustand intern bei, der durch methodenaufrufe verändert werden kann), daher muss man ein wenig zwischen den beiden Ansätzen abwägen (andererseits profitieren wir davon, dass mehrere Paradigmen in einer einzigen Sprache leicht zugänglich sind).

Also, drei Dinge, die man sich für jetzt merken sollte:

  1. Erfahren Sie, was Zuweisung in Ruby bedeutet: nichts anderes als die Benennung eines Objekts. Wenn Sie also sagen y=x, sagen Sie nur "wir geben einem anderen Namen y was auch immer unter x benannt ist".
  2. name << title verändert das Objekt mit dem Namen name.
  3. name += title nimmt die Objekte mit den Namen name und title, verknüpft sie zu einem anderen Objekt und weist diesem neuen Objekt den Namen name zu. Es verändert nichts.

0voto

rubyprince Punkte 17049

Ich bin auch auf eine solche Situation gestoßen und es endete in einem Fehler, den ich einen halben Tag lang herausfinden musste. Im Wesentlichen habe ich etwas wie das hier 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, dass die Variable file_name wieder auf ihren Ursprungswert gesetzt wird. Aber der object.file_name wurde geändert, da ich file_name.gsub! ausgeführt habe. Es gibt 2 Möglichkeiten, dies zu lösen. Ersetzen Sie entweder den .gsub! Aufruf durch file_name = file_name.gsub oder tun Sie file_name = object.file_name.dup. Ich entschied mich für die zweite Option.

Ich denke, wir sollten vorsichtig sein mit Methoden, die ! und << haben, da sie das ursprüngliche Objekt ändern, auf das sie wirken, insbesondere nach Zuweisungen wie dieser.

0voto

John Douthat Punkte 39886

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

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X