109 Stimmen

Was sind die Ruby Gotchas, vor denen ein Neuling gewarnt werden sollte?

Ich habe vor kurzem die Programmiersprache Ruby gelernt, und im Großen und Ganzen ist es eine gute Sprache. Aber ich war ziemlich überrascht, als ich feststellte, dass sie nicht so einfach ist, wie ich erwartet hatte. Genauer gesagt, schien mir die "Regel der geringsten Überraschung" nicht sehr beachtet zu werden (das ist natürlich sehr subjektiv). Zum Beispiel:

x = true and false
puts x  # displays true!

und die Berühmten:

puts "zero is true!" if 0  # zero is true!

Vor welchen anderen "Gotchas" würden Sie einen Ruby-Neuling warnen?

0 Stimmen

@phrases.insert(0, p) OK @phrases.insert(p) NICHTS passiert @phrases<<p # OK

0 Stimmen

Warum ist true and false true zurückgeben?

3 Stimmen

Denn "x = wahr und falsch" wird eigentlich als "(x = wahr) und falsch" interpretiert. Das ist eine Frage des Vorrangs der Operatoren: "und" hat eine niedrigere Priorität als "=". Die meisten anderen Sprachen haben die umgekehrte Priorität, ich weiß nicht, warum sie diese Reihenfolge in Rails gewählt haben, ich finde es sehr verwirrend. Wenn Sie das "normale" Verhalten wollen, geben Sie einfach "x = (true und false)" ein, dann wird x falsch sein.

8voto

karina Punkte 795

Eine sache, die ich gelernt habe, war, den Operator ||= sorgfältig zu verwenden. und besonders vorsichtig zu sein, wenn man mit booleschen Werten arbeitet. ich habe normalerweise a ||= b als Auffanglösung verwendet, um 'a' einen Standardwert zu geben, wenn alles andere fehlgeschlagen ist und 'a' gleich null bleibt. aber wenn a falsch und b wahr ist, dann wird a wahr zugewiesen.

0 Stimmen

Sie können verwenden a = b if a.nil? o @a = b unless defined?(@a) .

7voto

MiniQuark Punkte 43252

Ich hatte Probleme mit Mixins, die Instanzmethoden enthalten und Methoden der Klasse. Dieser Code könnte einem Neuling helfen:

module Displayable
  # instance methods here
  def display
    puts name
    self.class.increment_displays
  end
  def self.included(base)
    # This module method will be called automatically
    # after this module is included in a class.
    # We want to add the class methods to the class.
    base.extend Displayable::ClassMethods
  end
  module ClassMethods
    # class methods here
    def number_of_displays
      @number_of_displays # this is a class attribute
    end
    def increment_displays
      @number_of_displays += 1
    end
    def init_displays
      @number_of_displays = 0
    end
    # this module method will be called automatically
    # after this module is extended by a class.
    # We want to perform some initialization on a
    # class attribute.
    def self.extended(base)
      base.init_displays
    end
  end
end

class Person
  include Displayable
  def name; @name; end
  def initialize(name); @name=name; end
end

puts Person.number_of_displays # => 0
john = Person.new "John"
john.display # => John
puts Person.number_of_displays # => 1
jack = Person.new "Jack"
jack.display # => Jack
puts Person.number_of_displays # => 2

Zuerst dachte ich, ich könnte Module mit beiden Instanzmethoden haben und Methoden der Klasse, indem Sie dies einfach tun:

module Displayable
  def display
    puts name
    self.class.increment_displays
  end
  def self.number_of_displays  # WRONG!
    @number_of_displays
  end
  [...]
end

Leider ist die Methode Anzahl_der_Anzeigen wird niemals aufgenommen oder erweitert, da es sich um eine "Modulklassenmethode" handelt. Nur "Modulinstanzmethoden" können in eine Klasse aufgenommen (als Instanzmethoden) oder in eine Klasse erweitert werden (als Klassenmethoden). Aus diesem Grund müssen Sie die Instanzmethoden Ihres Mixins in ein Modul und die Klassenmethoden Ihres Mixins in ein anderes Modul aufnehmen (die Klassenmethoden nehmen Sie normalerweise in ein Submodul "ClassMethods" auf). Dank der inklusive können Sie sowohl Instanzmethoden als auch Klassenmethoden mit einem einfachen "include Displayable"-Aufruf einbinden (wie im obigen Beispiel gezeigt).

Dieses Mixin zählt jede Anzeige auf einer pro Klasse Basis. Der Zähler ist ein Klassenattribut, so dass jede Klasse ihre eigene hat (Ihr Programm wird wahrscheinlich fehlschlagen, wenn Sie eine neue Klasse von der Klasse Person ableiten, da die @Anzahl_der_Anzeigen Zähler für die abgeleitete Klasse wird nie initialisiert). Vielleicht möchten Sie @Anzahl_der_Anzeigen von @@Anzahl_der_Anzeigen um ihn zu einem globalen Zähler zu machen. In diesem Fall wird jede Klassenhierarchie ihren eigenen Zähler haben. Wenn Sie einen globalen und eindeutigen Zähler wünschen, sollten Sie ihn wahrscheinlich zu einem Modulattribut machen.

All das war für mich nicht intuitiv, als ich mit Ruby anfing.

Ich kann immer noch nicht herausfinden, wie man einige dieser Mixin-Methoden sauber privat oder geschützt machen, obwohl (nur die Anzeige y Anzahl_der_Anzeigen Methode sollte als öffentliche Methode aufgenommen werden).

6voto

Mike Woodhouse Punkte 50241

Ich denke " and " und " or " sind Anspielungen auf Perl, das einer der offensichtlicheren "Eltern" von Ruby ist (der andere ist Smalltalk). Beide haben einen viel niedrigeren Vorrang (niedriger als Zuweisung, woher das erwähnte Verhalten kommt) als && y || welches die Operatoren sind, die Sie verwenden sollten.

Es gibt noch andere Dinge zu beachten, die nicht auf den ersten Blick ersichtlich sind:

Man ruft nicht wirklich Methoden/Funktionen auf, auch wenn es irgendwie so aussieht. Stattdessen senden Sie, wie in Smalltalk, eine Nachricht an ein Objekt. Also method_missing ist eigentlich mehr wie message_not_understood .

some_object.do_something(args)

ist gleichbedeutend mit

some_object.send(:do_something, args) # note the :

Die Verwendung von Symbolen ist weit verbreitet. Das sind die Dinge, die beginnen mit : und sie sind nicht sofort ersichtlich (jedenfalls nicht für mich), aber je früher man sich mit ihnen auseinandersetzt, desto besser.

Ruby ist groß auf "Duck-Typing", nach dem Prinzip, dass "wenn es läuft wie eine Ente und quakt wie eine Ente...", die informelle Substitution von Objekten mit einer gemeinsamen Teilmenge von Methoden ohne explizite Vererbung oder mixin Beziehung erlaubt.

0 Stimmen

Danke. Es gibt eine Sache, die ich an der senden. Methode: Damit können Sie private Methoden auch außerhalb der Klasse aufrufen! Autsch.

1 Stimmen

@MiniQuark: Das ist es, was ich an der Sendemethode liebe!

5voto

Chirantan Punkte 14794

Verstehen des Unterschieds zwischen den Klassen Zeit und Datum. Beide sind unterschiedlich und haben bei ihrer Verwendung in Rails Probleme verursacht. Die Time-Klasse steht manchmal in Konflikt mit anderen Time-Klassen-Bibliotheken, die in der Standard-Ruby/Rails-Bibliothek vorhanden sind. Ich persönlich habe sehr viel Zeit gebraucht, um zu verstehen, was genau in meiner Rails-App vor sich geht. Später habe ich herausgefunden, dass ich

Time.new

Sie bezog sich auf eine Bibliothek an einem Ort, der mir gar nicht bekannt war.

Es tut mir leid, wenn ich mich nicht klar ausgedrückt habe, was ich genau sagen will. Wenn andere mit ähnlichen Problemen konfrontiert waren, erklären Sie es bitte noch einmal.

4voto

John Topley Punkte 110122

In der Vergangenheit ist mir aufgefallen, dass das Zeilenumbruchszeichen ( \n ) Escape-Sequenz wird - neben anderen - nicht von Zeichenketten in einfachen Anführungszeichen unterstützt. Der Backslash selbst wird escaped. Sie müssen doppelte Anführungszeichen verwenden, damit das Escaping wie erwartet funktioniert.

1 Stimmen

Und was ist der Unterschied zu anderen Sprachen?

0 Stimmen

Java, zum Beispiel. Einfache Anführungszeichen in Java können nur verwendet werden, um ein einzelnes Zeichen einzuschließen, nicht für Strings.

1 Stimmen

Dies entspricht jeder Sprache, die die Verwendung von einfachen Anführungszeichen für Zeichenketten zulässt, und ist der Grund, warum sie dies tun.

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