Articles

How to Write a Case Expression in Ruby

Posted on

Stellen Sie sich vor, Sie brauchen eine Möglichkeit, den Wert eines Objekts zu prüfen und darauf basierend eine andere Aktion durchzuführen. Der Weg der objektorientierten Programmierung ist die Verwendung von Polymorphismus, und wir werden gleich sehen, wie man das macht.

Aber zuerst wollen wir uns ansehen, wie der case-Ausdruck funktioniert und wie Sie ihn verwenden können, um das oben genannte Ziel zu erreichen.

Wie funktioniert Case?

Der case-Ausdruck besteht aus zwei Hauptteilen. Die case Klausel und die when Klausel.

Die when-Klausel ist der Ausdruck, der den Empfänger des Operators definiert (standardmäßig ===), und die case-Klausel definiert das Argument, das an ihn übergeben wird.

Lassen Sie uns ein Beispiel sehen.

case awhen String #..end

So können Sie sich das obige Beispiel als String === a vorstellen, oder String.===(a).

Schließlich gibt es auch eine else-Klausel, die Sie verwenden können, wenn es keine Übereinstimmung gibt.

case my_objectwhen String "This is a string"else "I have no idea what this is"end

Der dreifache Gleichheitsoperator (===)

Standardmäßig verwendet case den dreifachen Gleichheitsoperator (===), um den Vergleich durchzuführen.

Die Sache mit === ist, dass es nichts mit Gleichheit zu tun hat. Standardmäßig ist er auf den doppelten Gleichheitsoperator (==) verlinkt, der normalerweise prüft, ob zwei Objekte den gleichen Wert haben, aber er kann so definiert werden, dass er alles bedeutet.

Ein Bereich definiert ihn zum Beispiel als Alias für includes?, ein Regex definiert ihn als Alias für match, eine Klasse für is_a?, ein Proc für call. Sie verstehen schon.

Dieser Operator funktioniert wie erwartet mit Literalen, aber nicht mit Klassen:

1 === 1 # => trueNumeric === Numeric # => false

Das liegt daran, dass das === ein Alias für kind_of? ist. Und hier ist die Doku für kind_of?.

kind_of?(class) → true oder false

Returnt true, wenn class die Klasse von obj ist, oder wenn class eine der Superklassen von obj oder in obj enthaltene Module ist.

Das bedeutet, wenn Sie ein case ... when über die Klasse eines Objekts machen wollen, funktioniert das nicht:

obj = 'Hi'case obj.classwhen String "It's a string"end

Das liegt daran, dass es zu String === String übersetzt wird. Und das ergibt false.

Der Standardoperator

Der Ausdruck case hat einen Standardoperator. Und das bedeutet, dass Sie ihn nicht angeben müssen. Das ist sehr schön, denn Sie können einfach when String schreiben und es wird standardmäßig der ===-Operator verwendet.

Aber es gibt Zeiten, in denen Sie einen anderen Operator verwenden wollen. Und Ruby erlaubt es Ihnen, das zu tun. So geht’s.

casewhen a < 3 "Smaller than 3"end

Case ist ein Ausdruck

Wie der Name schon sagt, ist das Ganze ein Ausdruck. Das heißt, es wird zu einem Wert ausgewertet. Sie können also das Ergebnis des gesamten case Ausdrucks einer Variablen zuweisen, etwa so.

value = case when a < 3 "Smaller than 3" end

Es gibt kein Durchfallen

Wenn Sie aus anderen Sprachen kommen, haben Sie wahrscheinlich eine switch-Anweisung oder etwas Ähnliches verwendet, und Sie haben bemerkt, dass case keine Schlüsselwörter wie break verwendet, um den Fluss zu unterbrechen.

Das liegt daran, dass es mit case keinen Durchbruch gibt. Es gibt nur den Wert des Ausdrucks zurück, der übereinstimmt, und das war’s.

Mehrere Übereinstimmungen

Bis jetzt haben Sie nur einen Wert für die when-Klausel verwendet. Aber Sie können mehrere Werte verwenden.

case awhen 1..3 "Small number"end

Matching regexes

Sie können case Ausdrücke verwenden, um auf alles zu passen. Aber nur für den Fall, dass es nicht offensichtlich ist, können Sie auch Regexe oder Lambdas abgleichen. Hier ist ein Beispiel.

even = ->(x) { x % 2 == 0 }case awhen even "It's even"when /^+$/ "It's an integer"end

Definieren Sie Ihre eigenen

Eine der weniger bekannten Tatsachen ist, dass Sie Ihre eigenen Komparatoren definieren können.

Text = Struct.new(:min_length) do def ===(string) string.size > min_length && string.is_a?(String) endendcase awhen Text.new(100) "It's text"end

Wenn im obigen Beispiel a eine Zeichenkette mit mehr als 100 Zeichen ist, dann liefert der case-Ausdruck It's text.

Verwenden Sie stattdessen Polymorphismus

Ich werde hier nicht auf die Vorteile von OOP eingehen, Sie können mehr darüber im Artikel Objektorientierte Programmierung mit Ruby lesen, aber ich werde Ihnen zeigen, wie Sie Polymorphismus verwenden können, um einen case-Ausdruck zu ersetzen.

Die Case-Version

class Person attr_reader :country def initialize(country) @country = country end def nationality case country when "USA" "This guy is an American" when "Romania" "This guy is a Romanian" end endendjohn = Person.new("USA")puts john.nationality # => This guy is an American

Die OOP-Version

class Person attr_reader :country def initialize(country) @country = country end def nationality country.nationality endendclass America def nationality "This guy is an American" endendclass Romania def nationality "This guy is a Romanian" endendjohn = Person.new(America.new)puts john.nationality # => This guy is an American

Es ist eine gute Idee, so viel Flusskontrollcode (d.d. h. ifs, und case-Ausdrücke) wie möglich zu entfernen. Es verbessert die Einhaltung des Single-Responsibility-Prinzips und macht das Programm insgesamt lesbarer.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.