Sprawdź, czy zmienna jest łańcuchem w Rubim


Odpowiedzi:


206

Myślę, że szukasz instance_of?. is_a?i kind_of?zwróci wartość true dla wystąpień z klas pochodnych.

class X < String
end

foo = X.new

foo.is_a? String         # true
foo.kind_of? String      # true
foo.instance_of? String  # false
foo.instance_of? X       # true

9
Nie znając intencji pytania, powiedziałbym, że w przypadku większości rzeczywistych sytuacji programistycznych is_a?jest w rzeczywistości bardziej odpowiednim idiomem (a często sprawdzanie pisania na klawiaturze, o którym wspomina Andrew Grimm, jest jeszcze lepsze). Ścisłe porównanie klas to zwykle zapach kodu. en.wikipedia.org/wiki/Liskov_substitution_principle
mahemoff

Krótko na bok: jeśli używasz tego w logice warunkowej, musisz użyć nawiasów; np. jeśli foo.is_a? (String) && ...
dan

Zgodnie z oczekiwaniami to podejście będzie działać nie tylko z String, ale także z Integeri Float. Czy to też działa Decimal? (wzniosły interpreter tekstu inaczej podkreśla składnię, Decimalco sprawia, że ​​jestem podejrzliwy)
stevec

29

Można by powiedzieć, że bardziej typowe byłoby podejście do pisania na klawiaturze

foo.respond_to?(:to_str)

to_str wskazuje, że klasa obiektu może nie być rzeczywistym potomkiem String, ale sam obiekt jest bardzo podobny do ciągu (stringy?).


Chłodny. W tym przypadku zdarza mi się, że fooalbo będzie true, falsealbo ciąg wanilia, ale to dobrze, aby dowiedzieć się więcej ogólnych rozwiązań.
davidchambers

połącz to z wywołaniem to_s po sprawdzeniu, czy obiekt na niego odpowiada, a otrzymasz łańcuch!
seanmakesgames

1
@seanmakesgames Miałeś na myśli to_str, czy to_s? Te dwa są nieco inne.
Andrew Grimm,


23

Możesz to zrobić:

foo.instance_of?(String)

A bardziej ogólnie:

foo.kind_of?(String)

4
Co jest kind_ofbardziej ogólne? Wydają się być synonimem: is_a.
davidchambers

2
@Davidchambers masz rację, „kind_of?” jest synonimem „is_a?”.
steenslag

@davidchambers: Masz rację, miałem na myśli instance_of?zamiast is_a?.
Federico Builes

7
foo.instance_of? String

lub

foo.kind_of? String 

jeśli obchodzi cię tylko to, że pochodzi z Stringjakiegoś miejsca w łańcuchu dziedziczenia


4

Oprócz innych odpowiedzi, Class definiuje metodę === do sprawdzania, czy obiekt jest instancją tej klasy.

  • o.class klasa o.
  • o.instance_of? c określa, czy o.class == c
  • o.is_a? c Czy o jest instancją klasy c lub którejkolwiek z jej podklas?
  • o.kind_of? c synonim * is_a? *
  • c === o dla klasy lub modułu, określ, czy * o.is_a? c * ( String === "s" zwraca prawdę)

-1

Myślę, że lepszym sposobem jest stworzenie metod predykatów. Spowoduje to również zapisanie „pojedynczego punktu kontroli”.

class Object
 def is_string?
   false
 end
end

class String
 def is_string?
   true
 end
end

print "test".is_string? #=> true
print 1.is_string?      #=> false

Im bardziej kaczkowy sposób pisania;)


2
co jest nie tak z "string".is_a?(String). Wygląda na to, że odkrywasz koło na nowo. Jest też class, instance_of, kind_of, itd ... zły pomysł, aby małpa patch Objectklasa, nie wspominając, że to niepotrzebny.
Mohamad

Całkowicie się z Tobą zgadzam :) Jeśli skupiasz się tylko na typach pierwotnych i wiesz, że wymagania twojego projektu związane z typami pierwotnymi nigdy się nie zmienią (ok, tak to zwykle bywa;)) jest dobrze. Ale w przypadku, gdy wymagania się zmieniają, lepiej jest mieć „pojedynczy punkt kontroli”. Na przykład w środowisku projektu masz wiele wstępnych kontroli (1000 i więcej). pre_check("test".is_string?) Teraz wymagania twojego projektu ulegną zmianie i każdy łańcuch z trzema lub więcej znakami nie jest już zdefiniowany jako String (wiem, że jest niezwykły;)) Teraz możesz łatwo zmienić własną metodę.
schlegel11
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.