Periksa apakah suatu variabel adalah string di Ruby


Jawaban:


205

Saya pikir Anda sedang mencari instance_of?. is_a?dan kind_of?akan mengembalikan true untuk instance dari kelas turunan.

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
Tanpa mengetahui maksud pertanyaan tersebut, menurut saya untuk sebagian besar situasi pemrograman dunia nyata, is_a?sebenarnya adalah idiom yang lebih tepat untuk digunakan (dan seringkali cek mengetik bebek seperti yang disebutkan Andrew Grimm bahkan lebih baik). Perbandingan kelas yang ketat biasanya merupakan bau kode. en.wikipedia.org/wiki/Liskov_substitution_principle
mahemoff

Cepat singkirkan: jika Anda menggunakan ini dalam logika kondisional, Anda perlu menggunakan tanda kurung; misalnya, if foo.is_a? (String) && ...
dan

Seperti yang diharapkan, pendekatan ini akan bekerja tidak hanya dengan String, tetapi juga dengan Integerdan Float. Apakah itu juga berhasil Decimal? (penerjemah teks luhur menyoroti sintaks berbeda Decimalyang membuat saya curiga)
stevec

29

Pendekatan yang lebih mengetik bebek bisa dikatakan

foo.respond_to?(:to_str)

to_str menunjukkan bahwa kelas objek mungkin bukan turunan sebenarnya dari String, tetapi objek itu sendiri sangat mirip string (stringy?).


Keren. Dalam hal ini saya kebetulan tahu bahwa foobaik akan true, falseatau vanili string, tapi baik itu untuk belajar solusi yang lebih umum.
davidchambers

gabungkan ini dengan panggilan to_s setelah memeriksa apakah objek meresponnya, dan Anda mendapatkan sebuah string!
seanmakesgames

1
@seanmakesgames Apakah maksud Anda to_str, atau to_s? Keduanya sedikit berbeda.
Andrew Grimm


23

Anda dapat melakukan:

foo.instance_of?(String)

Dan yang lebih umum:

foo.kind_of?(String)

4
Apa yang membuatnya kind_oflebih umum? Mereka tampaknya identik: is_a.
davidchambers

2
@Davidchambers kau benar, 'kind_of?' adalah sinonim untuk 'is_a?'.
steenslag

@davidchambers: Anda benar, maksud saya, instance_of?bukan is_a?.
Federico Builes

7
foo.instance_of? String

atau

foo.kind_of? String 

jika Anda Anda hanya peduli jika itu diturunkan dari Stringsuatu tempat ke atas rantai warisannya


4

Selain jawaban lainnya, Kelas mendefinisikan metode === untuk menguji apakah suatu objek adalah turunan dari kelas itu.

  • o.class kelas o.
  • o.instance_of? c menentukan apakah o.class == c
  • o.is_a? c Apakah o turunan dari c atau salah satu subkelasnya?
  • baiklah? c sinonim untuk * is_a? *
  • c === o untuk kelas atau modul, tentukan apakah * o.is_a? c * ( String === "s" mengembalikan nilai true)

-1

Menurut saya cara yang lebih baik adalah dengan membuat beberapa metode predikat. Ini juga akan menyimpan "Titik Kontrol Tunggal" Anda.

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

Cara mengetik lebih bebek;)


2
ada apa dengan "string".is_a?(String). Sepertinya Anda menciptakan kembali kemudi. Ada juga class, instance_of, kind_of, dll ... Bad ide untuk monyet patch Objectkelas, belum lagi itu perlu.
Mohamad

Saya sangat setuju dengan Anda :) Jika fokus Anda hanya pada tipe primitif dan Anda tahu bahwa persyaratan proyek Anda yang terkait dengan tipe primitif tidak akan pernah berubah (ok biasanya terjadi;)) Anda baik-baik saja. Tetapi dalam kasus di mana persyaratan berubah lebih baik untuk memiliki "Titik Kontrol Tunggal". Misalnya di lingkungan proyek Anda, Anda memiliki banyak pemeriksaan awal (1000 dan lebih tinggi). pre_check("test".is_string?) Sekarang kebutuhan proyek Anda akan berubah dan setiap String dengan tiga karakter atau lebih tidak lagi didefinisikan sebagai String (saya tahu ini tidak biasa;)) Sekarang Anda dapat mengubah metode Anda sendiri dengan mudah.
schlegel11
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.