Inhalt | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11

Offizielle Ruby FAQ

Wenn Sie Fehler melden oder Verbesserungen für diese FAQ vorschlagen möchten, besuchen Sie bitte unser GitHub-Repository und öffnen Sie ein Issue oder einen Pull Request.

Syntax

Was ist der Unterschied zwischen einem sofortigen Wert und einer Referenz?

Dieser Abschnitt oder Teile davon könnten veraltet oder nicht bestätigt sein.

Fixnum, true, nil und false werden als sofortige Werte implementiert. Bei sofortigen Werten halten Variablen die Objekte selbst anstelle von Referenzen darauf.

Für solche Objekte können keine Singleton-Methoden definiert werden. Zwei Fixnums mit demselben Wert repräsentieren immer dieselbe Objektinstanz, daher werden (zum Beispiel) Instanzvariablen für die Fixnums mit dem Wert 1 zwischen allen 1en im System geteilt. Dies macht es unmöglich, eine Singleton-Methode nur für eine davon zu definieren.

Was ist der Unterschied zwischen nil und false?

Zuerst die Ähnlichkeit: nil und false sind die einzigen beiden Objekte, die in einem booleschen Kontext zu false ausgewertet werden. (Mit anderen Worten: Sie sind die einzigen „falsy“-Werte, alle anderen Objekte sind „truthy“.)

Jedoch sind nil und false Instanzen unterschiedlicher Klassen (NilClass und FalseClass) und haben woanders unterschiedliches Verhalten.

Wir empfehlen, dass Prädikatsmethoden (die, deren Name mit einem Fragezeichen endet) true oder false zurückgeben. Andere Methoden, die einen Fehler anzeigen müssen, sollten nil zurückgeben.

Warum ist ein leerer String nicht false?

F: Ein leerer String ("") gibt in einem bedingten Ausdruck true zurück! In Perl ist er false.

A: Aber Ruby ist nicht Perl ;-). Es ist sehr einfach: In Ruby sind nur nil und false in bedingten Kontexten falsch.

Sie können empty? verwenden, den String mit "" vergleichen oder die size oder length des Strings mit 0 vergleichen, um herauszufinden, ob ein String leer ist.

Was bedeutet :name?

Ein Doppelpunkt gefolgt von einem Namen erzeugt ein Symbol-Objekt, das eins zu eins mit dem Bezeichner korrespondiert. Während der Ausführungsdauer eines Programms wird für einen gegebenen Namen oder String dasselbe Symbol-Objekt erzeugt. Symbole können auch mit "name".intern oder "name".to_sym erstellt werden.

Symbol-Objekte können Bezeichner für Methoden, Variablen usw. darstellen. Einige Methoden, wie define_method, method_missing oder trace_var, erfordern ein Symbol. Andere Methoden, z. B. attr_accessor, send oder autoload, akzeptieren auch einen String.

Da sie nur einmal erstellt werden, werden Symbole oft als Hash-Schlüssel verwendet. String-Hash-Schlüssel würden bei jeder einzelnen Verwendung ein neues Objekt erstellen und dadurch einen gewissen Speicher-Overhead verursachen. Es gibt sogar eine spezielle Syntax für Symbol-Hash-Schlüssel.

person_1 = { :name => "John", :age => 42 }
person_2 = { name: "Jane", age: 24 }        # alternate syntax

Symbole können auch als Enumerationswerte verwendet werden oder um eindeutige Werte zu Konstanten zuzuweisen.

status = :open  # :closed, ...

NORTH = :NORTH
SOUTH = :SOUTH

Wie greife ich auf den Wert eines Symbols zu?

Um den Wert der Variable zu erhalten, die einem Symbol entspricht, können Sie symbol.to_s oder "#{symbol}" verwenden, um den Namen der Variable zu erhalten, und diese dann im Geltungsbereich des Symbols auswerten, um den Inhalt der Variable zu erhalten.

a = "This is the content of `a'"
b = eval("#{:a}")
a.object_id == b.object_id  # => true

Sie können auch verwenden

b = binding.local_variable_get(:a)

Wenn Ihr Symbol dem Namen einer Methode entspricht, können Sie send verwenden.

class Demo
  def hello
    "Hello, world"
  end
end

demo = Demo.new
demo.send(:hello)

Oder Sie können Object#method verwenden, um ein entsprechendes Method-Objekt zurückzugeben, das Sie dann aufrufen können.

m = demo.method(:hello)  # => #<Method: Demo#hello>
m.call                   # => "Hello, world"

Ist loop eine Kontrollstruktur?

Obwohl loop wie eine Kontrollstruktur aussieht, ist es tatsächlich eine Methode, die in Kernel definiert ist. Der folgende Block führt einen neuen Geltungsbereich für lokale Variablen ein.

Ruby hat keine Post-Test-Schleife

F: Ruby hat keine do { ... } while-Konstruktion, wie implementiere ich also Schleifen, die die Bedingung am Ende testen?

Clemens Hintze sagt: Sie können eine Kombination aus Rubys begin ... end und den while- oder until-Anweisungsmodifikatoren verwenden, um denselben Effekt zu erzielen.

i = 0
begin
  puts "i = #{i}"
  i += 1
end until i > 4

Erzeugt

i = 0
i = 1
i = 2
i = 3
i = 4

Warum kann ich kein Hash-Literal an eine Methode übergeben: p {}?

Das {} wird als Block und nicht als Hash-Konstruktor geparst. Sie können erzwingen, dass {} als Ausdruck behandelt wird, indem Sie die Tatsache, dass es sich um einen Parameter handelt, explizit machen: p({}).

Ich kann def pos=(val) nicht zum Laufen bringen!

Ich habe den folgenden Code, kann aber die Methode pos = 1 nicht verwenden.

def pos=(val)
  @pos = val
  puts @pos
end

Methoden mit angehängtem = müssen mit einem expliziten Empfänger aufgerufen werden (ohne den Empfänger weisen Sie einfach einer lokalen Variable zu). Rufen Sie es als self.pos = 1 auf.

Was ist der Unterschied zwischen '\1' und '\\1'?

Sie haben dieselbe Bedeutung. In einem einfach Anführungszeichen-String werden nur \' und \\ transformiert und andere Kombinationen bleiben unverändert.

Jedoch ist in einem doppelt Anführungszeichen-String "\1" das Byte \001 (ein Oktalmuster), während "\\1" der Zwei-Zeichen-String ist, der einen Backslash und das Zeichen "1" enthält.

Was ist der Unterschied zwischen .. und ...?

.. schließt die rechte Seite in den Bereich ein, ... nicht.

(5..8).to_a   # => [5, 6, 7, 8]
(5...8).to_a  # => [5, 6, 7]

Was ist der Unterschied zwischen or und ||?

F: p(nil || "Hallo") gibt "Hallo" aus, während p(nil or "Hallo") einen Parse-Fehler ergibt. Warum?

A: or hat eine sehr niedrige Präzedenz, p( (nil or "Hallo") ) funktioniert.

Die Präzedenz von or ist zum Beispiel auch niedriger als die von =, während || eine höhere Präzedenz hat.

foo = nil || "Hello"  # parsed as: foo = (nil || "Hello")
foo  # => "Hello"

# but perhaps surprisingly:

foo = nil or "Hello"  # parsed as: (foo = nil) or "Hello"
foo  # => nil

or (und ähnlich and) wird am besten **nicht** zum Kombinieren von booleschen Ausdrücken verwendet, sondern zur Flusskontrolle, wie in

do_something  or raise "some error!"

wo do_something false oder nil zurückgibt, wenn ein Fehler auftritt.

Hat Ruby Funktionszeiger?

Ein Proc-Objekt, das von Proc.new, proc oder lambda erzeugt wird, kann aus einer Variable referenziert werden, sodass diese Variable als Funktionszeiger bezeichnet werden könnte. Sie können auch Referenzen auf Methoden innerhalb einer bestimmten Objektinstanz mit object.method erhalten.

Was ist der Unterschied zwischen load und require?

load lädt und führt ein Ruby-Programm (*.rb) aus.

require lädt ebenfalls Ruby-Programme, lädt aber auch binäre Ruby-Erweiterungsmodule (Shared Libraries oder DLLs). Zusätzlich stellt require sicher, dass ein Feature nie mehr als einmal geladen wird.

Hat Ruby Ausnahmebehandlung?

Ruby unterstützt ein flexibles Ausnahmebehandlungssystem.

begin
  statements which may raise exceptions
rescue [exception class names]
  statements when an exception occurred
rescue [exception class names]
  statements when an exception occurred
ensure
  statements that will always run
end

Wenn im begin-Block eine Ausnahme auftritt, wird die rescue-Klausel mit dem übereinstimmenden Ausnahmsnamen ausgeführt. Die ensure-Klausel wird unabhängig davon ausgeführt, ob eine Ausnahme aufgetreten ist oder nicht. rescue- und ensure-Klauseln können weggelassen werden.

Wenn für eine rescue-Klausel keine Ausnahmeklasse angegeben ist, wird die Ausnahme StandardError impliziert, und Ausnahmen, die sich in einer is_a?-Beziehung zu StandardError befinden, werden erfasst.

Dieser Ausdruck gibt den Wert des begin-Blocks zurück.

Die letzte Ausnahme wird über die globale Variable $! abgerufen (und ihr Typ kann über $!.type bestimmt werden).