อะไรคือความแตกต่าง - ทางเทคนิคปรัชญาแนวคิดหรืออื่น ๆ - ระหว่าง
raise "foo"
และ
raise Exception.new("foo")
เหรอ?
อะไรคือความแตกต่าง - ทางเทคนิคปรัชญาแนวคิดหรืออื่น ๆ - ระหว่าง
raise "foo"
และ
raise Exception.new("foo")
เหรอ?
คำตอบ:
เทคนิคแรกยก Runtimeerror กับชุดข้อความไปยังและที่สองทำให้เกิดข้อยกเว้นกับชุดข้อความไปยัง"foo"
"foo"
ในทางปฏิบัติมีความแตกต่างอย่างมีนัยสำคัญระหว่างเวลาที่คุณต้องการใช้อดีตและเมื่อคุณต้องการใช้แบบหลัง
พูดง่ายๆก็คือคุณอาจRuntimeError
ไม่ต้องการไฟล์Exception
. บล็อกช่วยเหลือที่ไม่มีข้อโต้แย้งจะจับRuntimeErrors
ได้ แต่จะไม่จับException
s ดังนั้นหากคุณเพิ่มException
รหัสของคุณรหัสนี้จะไม่จับมัน:
begin
rescue
end
ในการจับException
คุณจะต้องทำสิ่งนี้:
begin
rescue Exception
end
ซึ่งหมายความว่าในแง่หนึ่งException
ข้อผิดพลาด "แย่กว่า" มากกว่า a RuntimeError
เนื่องจากคุณต้องทำงานมากขึ้นเพื่อกู้คืนจากข้อผิดพลาดนั้น
สิ่งที่คุณต้องการขึ้นอยู่กับว่าโครงการของคุณจัดการข้อผิดพลาดอย่างไร ตัวอย่างเช่นในภูตของเราลูปหลักมีการช่วยเหลือว่างซึ่งจะจับRuntimeErrors
รายงานและดำเนินการต่อ แต่ในหนึ่งหรือสองสถานการณ์เราต้องการให้ภูตตายด้วยข้อผิดพลาดจริงๆและในกรณีนี้เราจะเพิ่มขึ้นException
ซึ่งจะส่งผ่าน "รหัสการจัดการข้อผิดพลาดปกติ" ของเราโดยตรงและออก
และอีกครั้งหากคุณกำลังเขียนโค้ดไลบรารีคุณอาจต้องการ a RuntimeError
ไม่ใช่Exception
เนื่องจากผู้ใช้ห้องสมุดของคุณจะแปลกใจหากเกิดข้อผิดพลาดที่rescue
บล็อกว่างไม่สามารถจับได้และพวกเขาจะต้องใช้เวลาสักครู่ในการทราบสาเหตุ
สุดท้ายฉันควรจะบอกว่าRuntimeError
เป็นคลาสย่อยของStandardError
คลาสและกฎที่แท้จริงก็คือแม้ว่าคุณจะสามารถอ็อบเจ็กต์ประเภทraise
ใดก็ได้rescue
แต่ค่าเริ่มต้นจะจับเฉพาะสิ่งที่สืบทอดมาStandardError
เท่านั้น อย่างอื่นต้องมีความเฉพาะเจาะจง
StandardError
เมื่อฉันเขียนโปรแกรมที่มืออาชีพมากที่สุดของฉันฉันมีแนวโน้มที่จะสร้างข้อผิดพลาดประเภทที่กำหนดเองที่สืบทอดมาจาก ไม่จำเป็นต้องซับซ้อนกว่าสองสามบรรทัดเช่นclass MissingArgumentsError < StandardError; end
.
raise
raise( string )
raise( exception [, string [, array ] ] )
หากไม่มีข้อโต้แย้งจะทำให้เกิดข้อยกเว้น$!
หรือเพิ่มRuntimeError
if $!
เป็นศูนย์ ด้วยString
อาร์กิวเมนต์เดียวจะเพิ่มRuntimeError
สตริงเป็นข้อความ มิฉะนั้นพารามิเตอร์แรกควรเป็นชื่อของException
คลาส (หรืออ็อบเจ็กต์ที่ส่งคืนException
ข้อยกเว้นเมื่อส่ง) พารามิเตอร์ที่สองซึ่งเป็นทางเลือกจะตั้งค่าข้อความที่เกี่ยวข้องกับข้อยกเว้นและพารามิเตอร์ที่สามคืออาร์เรย์ของข้อมูลการเรียกกลับ ข้อยกเว้นถูกจับโดยประโยคช่วยเหลือของbegin...end
บล็อก
raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
RuntimeError < StandardError < Exception
[2] ดังนั้นโค้ดบล็อกที่สองจะจับทั้ง Exception และ RuntimeError [3] มันน่าสนใจ / แปลกที่การเพิ่มและช่วยเหลือแบบ "เปล่า" เกิดขึ้นเพื่อทำงานกับข้อยกเว้นนั้น ๆ [4] บางทีหลักการง่ายๆคือการเพิ่ม RuntimeError ให้กับรหัสไคลเอ็นต์ แต่เพิ่มและช่วยเหลือข้อยกเว้นที่กำหนดเองภายในรหัสของตัวเอง?