ตรวจสอบว่าตัวแปรเป็นสตริงใน Ruby หรือไม่


คำตอบ:


205

instance_of?ฉันคิดว่าคุณกำลังมองหา is_a?และkind_of?จะคืนค่าจริงสำหรับอินสแตนซ์จากคลาสที่ได้รับ

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
โดยไม่ทราบเจตนาของคำถามฉันจะบอกว่าสำหรับสถานการณ์การเขียนโปรแกรมในโลกแห่งความis_a?เป็นจริงส่วนใหญ่เป็นสำนวนที่เหมาะสมกว่าที่จะใช้ (และบ่อยครั้งการตรวจสอบการพิมพ์เป็ดอย่างที่ Andrew Grimm กล่าวถึงนั้นดีกว่า) การเปรียบเทียบชั้นเรียนที่เข้มงวดมักจะเป็นกลิ่นรหัส en.wikipedia.org/wiki/Liskov_substitution_principle
mahemoff

กันอย่างรวดเร็ว: หากคุณใช้สิ่งนี้ในตรรกะเงื่อนไขคุณต้องใช้วงเล็บ เช่นถ้า foo.is_a (String) && ... ?
แดน

คาดว่าจะเป็นวิธีการนี้จะทำงานไม่เพียง แต่มีStringแต่ยังมีและInteger Floatมันยังใช้ได้กับDecimal? (ล่ามข้อความประเสริฐไฮไลท์ไวยากรณ์ที่แตกต่างกันสำหรับการDecimalที่ทำให้ฉันสงสัย)
stevec

29

วิธีการพิมพ์เป็ดมากขึ้นคือการพูด

foo.respond_to?(:to_str)

to_str บ่งชี้ว่าคลาสของอ็อบเจ็กต์อาจไม่ใช่ผู้สืบทอดที่แท้จริงของ String แต่อ็อบเจ็กต์นั้นมีลักษณะคล้ายสตริงมาก (stringy?)


เย็น. ในกรณีนี้ผมก็เพิ่งจะรู้ว่าfooทั้งสองจะเป็นtrue, falseหรือสตริงวานิลลา แต่มันเป็นเรื่องดีที่จะเรียนรู้การแก้ปัญหาทั่วไปมากขึ้น
davidchambers

รวมสิ่งนี้เข้ากับการเรียก to_s หลังจากตรวจสอบว่าวัตถุตอบสนองต่อมันหรือไม่และคุณมีสตริงด้วยตัวเอง!
seanmakesgames

1
@seanmakesgames คุณหมายถึงto_strหรือto_s? ทั้งสองแตกต่างกันเล็กน้อย
Andrew Grimm

stackoverflow.com/questions/11182052/… Re: ความคิดเห็นของ andrew.
seanmakesgames

23

คุณทำได้:

foo.instance_of?(String)

และทั่วไปมากขึ้น:

foo.kind_of?(String)

4
อะไรทำให้kind_ofทั่วไปมากขึ้น? is_aพวกเขาดูเหมือนจะเป็นความหมายเหมือนกัน:
davidchambers

2
@Davidchambers คุณพูดถูก 'kind_of?' เป็นคำพ้องความหมายสำหรับ 'is_a?'
steenslag

@davidchambers: คุณขวาฉันหมายแทนinstance_of? is_a?
Federico Builes

7
foo.instance_of? String

หรือ

foo.kind_of? String 

หากคุณสนใจเพียงว่ามันมาจากที่Stringใดที่หนึ่งในห่วงโซ่มรดก


4

นอกจากคำตอบอื่น ๆ แล้ว Class ยังกำหนดวิธีการ === เพื่อทดสอบว่าออบเจ็กต์เป็นอินสแตนซ์ของคลาสนั้นหรือไม่

  • o.classคลาสของ o
  • o.instance_of? cกำหนดว่าo.class == c
  • o.is_a? คเป็นตัวอย่างของ c หรือคลาสย่อยใด ๆ หรือไม่?
  • o.kind_of? คไวพจน์สำหรับ * is_a? *
  • c === oสำหรับคลาสหรือโมดูลให้พิจารณาว่า * o.is_a? c * ( String === "s"คืนค่าจริง)

-1

ฉันคิดว่าวิธีที่ดีกว่าคือการสร้างวิธีการเพรดิเคต วิธีนี้จะบันทึก "จุดควบคุมจุดเดียว" ของคุณด้วย

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

วิธีการพิมพ์เป็ดมากขึ้น;)


2
"string".is_a?(String)อะไรผิดปกติกับ ดูเหมือนว่าคุณกำลังคิดค้นล้อใหม่ นอกจากนี้ยังมีclass, instance_of, kind_ofฯลฯ ... ความคิดที่ดีที่จะแพทช์ลิงObjectชั้นไม่พูดถึงมันไม่มีความจำเป็น
Mohamad

ฉันเห็นด้วยกับคุณโดยสิ้นเชิง :) หากคุณมุ่งเน้นไปที่ประเภท primitve เท่านั้นและคุณรู้ว่าความต้องการโครงการของคุณที่เกี่ยวข้องกับประเภทดั้งเดิมจะไม่มีวันเปลี่ยนแปลง (ตกลงเป็นกรณีปกติ;)) คุณก็สบายดี แต่ในกรณีที่ข้อกำหนดเปลี่ยนไปให้มี "จุดควบคุมจุดเดียว" ดีกว่า ตัวอย่างเช่นในสภาพแวดล้อมโครงการของคุณคุณมีการตรวจสอบล่วงหน้าจำนวนมาก (1,000 ขึ้นไป) pre_check("test".is_string?) ตอนนี้ความต้องการโครงการของคุณจะเปลี่ยนไปและทุก ๆ String ที่มีอักขระสามตัวขึ้นไปจะไม่ถูกกำหนดให้เป็น String อีกต่อไป (ฉันรู้ว่ามันผิดปกติ;)) ตอนนี้คุณสามารถเปลี่ยนวิธีการของคุณเองได้อย่างง่ายดาย
schlegel11
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.