เพื่อตรวจสอบว่า@some_var
คืออะไรฉันกำลังทำไฟล์
if @some_var.class.to_s == 'Hash'
ผมมั่นใจว่ามีวิธีที่สง่างามมากขึ้นเพื่อตรวจสอบว่า@some_var
เป็นหรือHash
Array
เพื่อตรวจสอบว่า@some_var
คืออะไรฉันกำลังทำไฟล์
if @some_var.class.to_s == 'Hash'
ผมมั่นใจว่ามีวิธีที่สง่างามมากขึ้นเพื่อตรวจสอบว่า@some_var
เป็นหรือHash
Array
[result_hash, another_result_hash]
หรือsingle_result_hash
? ใครก็ตามที่สร้าง API นั้นทำงานได้ไม่ดี!
คำตอบ:
คุณสามารถทำได้:
@some_var.class == Hash
หรือสิ่งที่ชอบ:
@some_var.is_a?(Hash)
เป็นที่น่าสังเกตว่า "is_a?" เมธอดเป็นจริงถ้าคลาสอยู่ที่ใดก็ได้ในแผนผังบรรพบุรุษของอ็อบเจ็กต์ ตัวอย่างเช่น:
@some_var.is_a?(Object) # => true
ข้างต้นเป็นจริงถ้า @some_var เป็นอินสแตนซ์ของแฮชหรือคลาสอื่น ๆ ที่เกิดจาก Object ดังนั้นหากคุณต้องการจับคู่ประเภทคลาสอย่างเข้มงวดโดยใช้ == หรือ instance_of? วิธีการอาจเป็นสิ่งที่คุณกำลังมองหา
is_a?
เป็นตัวเลือกที่ดีที่สุดเนื่องจากจะส่งคืนtrue
สำหรับคลาสย่อยด้วย
@som_var.is_a? Hash
ด้วยก็ใช้ได้เช่นกัน :)
ActiveSupport::HashWithIndifferentAccess
สืบทอดมาจาก Hash ดังนั้น@some_var.is_a?(Hash)
จะกลับมาเป็นจริงในกรณีนี้เช่นกัน (ฉันเพิ่งมีคำถามเดียวกันและกรณี HashWithIndifferentAccess และสับสนเล็กน้อยจากความคิดเห็นของคุณ ... ฉันจึงอยากชี้แจง)
ก่อนอื่นคำตอบที่ดีที่สุดสำหรับคำถามตามตัวอักษรคือ
Hash === @some_var
แต่คำถามควรได้รับคำตอบจริงๆโดยแสดงวิธีการพิมพ์เป็ดที่นี่ ขึ้นอยู่กับว่าคุณต้องการเป็ดแบบไหน
@some_var.respond_to?(:each_pair)
หรือ
@some_var.respond_to?(:has_key?)
หรือแม้กระทั่ง
@some_var.respond_to?(:to_hash)
อาจถูกต้องขึ้นอยู่กับการใช้งาน
โดยปกติในทับทิมเมื่อคุณกำลังมองหา "ประเภท" คุณต้องการ "แบบเป็ด" หรือ "ต้มตุ๋นเหมือนเป็ด?" คุณจะเห็นว่ามันตอบสนองต่อวิธีการบางอย่างหรือไม่:
@some_var.respond_to?(:each)
คุณสามารถวนซ้ำได้ที่ @some_var เพราะมันตอบสนองต่อ: each
หากคุณต้องการทราบประเภทจริงๆและถ้าเป็น Hash หรือ Array คุณสามารถทำได้:
["Hash", "Array"].include?(@some_var.class) #=> check both through instance class
@some_var.kind_of?(Hash) #=> to check each at once
@some_var.is_a?(Array) #=> same as kind_of
sort
มาก่อน
["Hash", "Array"].include?(@some_var.class.to_s) #=> check both through instance class
Hash === @some_var #=> return Boolean
สามารถใช้กับ case statement
case @some_var
when Hash
...
when Array
...
end
ฉันใช้สิ่งนี้:
@var.respond_to?(:keys)
ใช้งานได้กับ Hash และ ActiveSupport :: HashWithIndifferentAccess
ในทางปฏิบัติคุณมักจะต้องการดำเนินการที่แตกต่างกันขึ้นอยู่กับว่าตัวแปรนั้นเป็น Array หรือ Hash ไม่ใช่แค่บอกเท่านั้น ในสถานการณ์เช่นนี้สำนวนที่สวยงามมีดังต่อไปนี้:
case item
when Array
#do something
when Hash
#do something else
end
โปรดทราบว่าคุณไม่ได้เรียกใช้.class
เมธอดitem
นี้
คุณสามารถใช้ได้ instance_of?
เช่น
@some_var.instance_of?(Hash)
ActiveRecord::Collection
และพยายามที่instance_of?(Array)
แล้วนี้จะกลับมาfalse
ในขณะที่จะกลับมาis_a?(Array)
true
หากคุณต้องการทดสอบว่าวัตถุนั้นเคร่งครัดหรือขยาย a Hash
ให้ใช้:
value = {}
value.is_a?(Hash) || value.is_a?(Array) #=> true
แต่เพื่อสร้างมูลค่าให้กับการพิมพ์เป็ดของ Ruby คุณสามารถทำสิ่งต่อไปนี้:
value = {}
value.respond_to?(:[]) #=> true
มีประโยชน์เมื่อคุณต้องการเข้าถึงค่าบางอย่างโดยใช้value[:key]
ไวยากรณ์เท่านั้น
โปรดทราบว่า
Array.new["key"]
จะเพิ่มไฟล์TypeError
.
irb(main):005:0> {}.class
=> Hash
irb(main):006:0> [].class
=> Array