Operatory równości: == i! =
Operator ==, znany również jako równość lub podwójna równość, zwróci true, jeśli oba obiekty są równe, a false, jeśli nie są.
"koan" == "koan" # Output: => true
Operator! =, Znany również jako nierówność, jest przeciwieństwem ==. Zwróci wartość true, jeśli oba obiekty nie są równe, i false, jeśli są równe.
"koan" != "discursive thought" # Output: => true
Zauważ, że dwie tablice z tymi samymi elementami w innej kolejności nie są równe, wielkie i małe wersje tej samej litery nie są równe i tak dalej.
Podczas porównywania liczb różnych typów (np. Liczba całkowita i liczba zmiennoprzecinkowa), jeśli ich wartość liczbowa jest taka sama, == zwróci wartość true.
2 == 2.0 # Output: => true
równy?
W przeciwieństwie do operatora ==, który sprawdza, czy oba argumenty są równe, metoda równości sprawdza, czy dwa argumenty odnoszą się do tego samego obiektu. Jest to najostrzejsza forma równości w Rubim.
Przykład: a = „zen” b = „zen”
a.object_id # Output: => 20139460
b.object_id # Output :=> 19972120
a.equal? b # Output: => false
W powyższym przykładzie mamy dwa ciągi o tej samej wartości. Są to jednak dwa odrębne obiekty o różnych identyfikatorach obiektów. Stąd równy? metoda zwróci false.
Spróbujmy jeszcze raz, tylko tym razem b będzie odniesieniem do a. Zauważ, że identyfikator obiektu jest taki sam dla obu zmiennych, ponieważ wskazują one na ten sam obiekt.
a = "zen"
b = a
a.object_id # Output: => 18637360
b.object_id # Output: => 18637360
a.equal? b # Output: => true
eql?
W klasie Hash eql? metoda służy do testowania kluczy pod kątem równości. Aby to wyjaśnić, wymagane jest pewne doświadczenie. W ogólnym kontekście obliczeń funkcja skrótu pobiera ciąg (lub plik) o dowolnym rozmiarze i generuje ciąg lub liczbę całkowitą o stałym rozmiarze, zwaną hashcode, zwaną zwykle hashem. Niektóre powszechnie używane typy skrótów to MD5, SHA-1 i CRC. Są one używane w algorytmach szyfrowania, indeksowaniu baz danych, sprawdzaniu integralności plików itp. Niektóre języki programowania, takie jak Ruby, zapewniają typ kolekcji zwany tablicą skrótów. Tabele skrótów są kolekcjami przypominającymi słownik, które przechowują dane w parach, składające się z unikalnych kluczy i odpowiadających im wartości. Pod maską te klucze są przechowywane jako kody skrótu. Tabele skrótów są powszechnie nazywane skrótami. Zauważ, jak słowo hashcan może odnosić się do hashcode lub do tablicy hash.
Ruby zapewnia wbudowaną metodę zwaną hash do generowania skrótów. W poniższym przykładzie pobiera ciąg znaków i zwraca kod skrótu. Zauważ, że ciągi o tej samej wartości zawsze mają ten sam kod skrótu, nawet jeśli są odrębnymi obiektami (o różnych identyfikatorach obiektów).
"meditation".hash # Output: => 1396080688894079547
"meditation".hash # Output: => 1396080688894079547
"meditation".hash # Output: => 1396080688894079547
Metoda skrótu jest zaimplementowana w module jądra, zawartym w klasie Object, która jest domyślnym katalogiem głównym wszystkich obiektów Ruby. Niektóre klasy, takie jak Symbol i Integer, używają domyślnej implementacji, inne jak String i Hash zapewniają własne implementacje.
Symbol.instance_method(:hash).owner # Output: => Kernel
Integer.instance_method(:hash).owner # Output: => Kernel
String.instance_method(:hash).owner # Output: => String
Hash.instance_method(:hash).owner # Output: => Hash
W Ruby, kiedy przechowujemy coś w haszu (kolekcji), obiekt podany jako klucz (np. Łańcuch lub symbol) jest konwertowany i zapisywany jako kod skrótu. Później, podczas pobierania elementu z skrótu (kolekcji), udostępniamy obiekt jako klucz, który jest konwertowany na kod skrótu i porównywany z istniejącymi kluczami. Jeśli istnieje dopasowanie, zwracana jest wartość odpowiedniego elementu. Porównanie odbywa się za pomocą eql? metoda pod maską.
"zen".eql? "zen" # Output: => true
# is the same as
"zen".hash == "zen".hash # Output: => true
W większości przypadków eql? Metoda zachowuje się podobnie do metody ==. Jest jednak kilka wyjątków. Na przykład eql? nie wykonuje niejawnej konwersji typu podczas porównywania liczby całkowitej z liczbą zmiennoprzecinkową.
2 == 2.0 # Output: => true
2.eql? 2.0 # Output: => false
2.hash == 2.0.hash # Output: => false
Operator równości wielkości: ===
Wiele wbudowanych klas Ruby, takich jak String, Range i Regexp, zapewnia własne implementacje operatora ===, znanego również jako równość wielkości liter, potrójne równe lub trzykwale. Ponieważ jest zaimplementowany inaczej w każdej klasie, będzie zachowywać się inaczej w zależności od typu obiektu, do którego został wywołany. Zasadniczo zwraca wartość true, jeśli obiekt po prawej „należy do” lub „jest członkiem” obiektu po lewej stronie. Na przykład można go użyć do przetestowania, czy obiekt jest instancją klasy (lub jednej z jej podklas).
String === "zen" # Output: => true
Range === (1..2) # Output: => true
Array === [1,2,3] # Output: => true
Integer === 2 # Output: => true
Ten sam wynik można osiągnąć za pomocą innych metod, które prawdopodobnie najlepiej nadają się do pracy. Zwykle lepiej jest napisać kod, który jest łatwy do odczytania, tak wyraźny, jak to możliwe, bez poświęcania wydajności i zwięzłości.
2.is_a? Integer # Output: => true
2.kind_of? Integer # Output: => true
2.instance_of? Integer # Output: => false
Zwróć uwagę, że ostatni przykład zwrócił wartość false, ponieważ liczby całkowite, takie jak 2, są instancjami klasy Fixnum, która jest podklasą klasy Integer. ===, is_a? i instance_of? metody zwracają wartość true, jeśli obiekt jest instancją danej klasy lub dowolnej podklasy. Metoda instance_of jest bardziej rygorystyczna i zwraca true tylko wtedy, gdy obiekt jest instancją tej właśnie klasy, a nie podklasą.
Czy to jest? i rodzaj? metody są zaimplementowane w module jądra, który jest mieszany przez klasę Object. Oba są pseudonimami tej samej metody. Sprawdźmy:
Kernel.instance_method (: kind_of?) == Kernel.instance_method (: is_a?) # Output: => true
Zakres realizacji ===
Gdy operator === jest wywoływany na obiekcie zakresu, zwraca wartość true, jeśli wartość po prawej stronie mieści się w zakresie po lewej stronie.
(1..4) === 3 # Output: => true
(1..4) === 2.345 # Output: => true
(1..4) === 6 # Output: => false
("a".."d") === "c" # Output: => true
("a".."d") === "e" # Output: => false
Pamiętaj, że operator === wywołuje metodę === obiektu po lewej stronie. Więc (1..4) === 3 jest równoważne z (1..4). === 3. Innymi słowy, klasa operandu po lewej stronie określi, która implementacja metody === będzie wywołane, więc pozycje operandu nie są zamienne.
Implementacja Regexp ===
Zwraca true, jeśli ciąg po prawej stronie pasuje do wyrażenia regularnego po lewej. / zen / === „ćwiczenie zazen dzisiaj” # Wyjście: => true # to to samo co „ćwiczenie zazen dzisiaj” = ~ / zen /
Niejawne użycie operatora === w instrukcjach case / when
Ten operator jest również używany pod maską na instrukcjach dotyczących przypadków / kiedy. To jest jego najczęstsze zastosowanie.
minutes = 15
case minutes
when 10..20
puts "match"
else
puts "no match"
end
# Output: match
W powyższym przykładzie, gdyby Ruby domyślnie zastosowała operator podwójnej równości (==), zakres 10..20 nie byłby uważany za równy liczbie całkowitej, takiej jak 15. Pasują, ponieważ potrójny operator równości (===) to domyślnie używane we wszystkich instrukcjach case / when. Kod w powyższym przykładzie jest równoważny z:
if (10..20) === minutes
puts "match"
else
puts "no match"
end
Operatory dopasowywania wzorców: = ~ i! ~
Operatory = ~ (równa tylda) i! ~ (Bang-tylda) służą do dopasowania ciągów i symboli do wzorców wyrażeń regularnych.
Implementacja metody = ~ w klasach String i Symbol oczekuje wyrażenia regularnego (instancji klasy Regexp) jako argumentu.
"practice zazen" =~ /zen/ # Output: => 11
"practice zazen" =~ /discursive thought/ # Output: => nil
:zazen =~ /zen/ # Output: => 2
:zazen =~ /discursive thought/ # Output: => nil
Implementacja w klasie Regexp oczekuje ciągu lub symbolu jako argumentu.
/zen/ =~ "practice zazen" # Output: => 11
/zen/ =~ "discursive thought" # Output: => nil
We wszystkich implementacjach, gdy ciąg lub symbol pasuje do wzorca Regexp, zwraca liczbę całkowitą, która jest pozycją (indeksem) dopasowania. Jeśli nie ma dopasowania, zwraca zero. Pamiętaj, że w Rubim każda wartość całkowita jest „prawda”, a zero to „fałsz”, więc operator = ~ może być użyty w instrukcjach if i operatorach trójskładnikowych.
puts "yes" if "zazen" =~ /zen/ # Output: => yes
"zazen" =~ /zen/?"yes":"no" # Output: => yes
Operatory dopasowywania wzorców są również przydatne do pisania krótszych instrukcji if. Przykład:
if meditation_type == "zazen" || meditation_type == "shikantaza" || meditation_type == "kinhin"
true
end
Can be rewritten as:
if meditation_type =~ /^(zazen|shikantaza|kinhin)$/
true
end
Operator! ~ Jest przeciwieństwem = ~, zwraca true, gdy nie ma dopasowania, i false, jeśli istnieje dopasowanie.
Więcej informacji jest dostępnych w tym poście na blogu .
"a" == "a"
,"a" === "a"
i"a".eql? "a"
. Ale to nieprawda:"a".equal? "a"
(Mój jest rubinowy 1.9.2-p180)