อะไรคือความแตกต่าง - ทางเทคนิคปรัชญาแนวคิดหรืออื่น ๆ - ระหว่าง
raise "foo"
และ
raise Exception.new("foo")
เหรอ?
อะไรคือความแตกต่าง - ทางเทคนิคปรัชญาแนวคิดหรืออื่น ๆ - ระหว่าง
raise "foo"
และ
raise Exception.new("foo")
เหรอ?
คำตอบ:
เทคนิคแรกยก Runtimeerror กับชุดข้อความไปยังและที่สองทำให้เกิดข้อยกเว้นกับชุดข้อความไปยัง"foo""foo"
ในทางปฏิบัติมีความแตกต่างอย่างมีนัยสำคัญระหว่างเวลาที่คุณต้องการใช้อดีตและเมื่อคุณต้องการใช้แบบหลัง
พูดง่ายๆก็คือคุณอาจRuntimeErrorไม่ต้องการไฟล์Exception. บล็อกช่วยเหลือที่ไม่มีข้อโต้แย้งจะจับRuntimeErrorsได้ แต่จะไม่จับExceptions ดังนั้นหากคุณเพิ่ม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 ] ] )
หากไม่มีข้อโต้แย้งจะทำให้เกิดข้อยกเว้น$!หรือเพิ่มRuntimeErrorif $!เป็นศูนย์ ด้วย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 ให้กับรหัสไคลเอ็นต์ แต่เพิ่มและช่วยเหลือข้อยกเว้นที่กำหนดเองภายในรหัสของตัวเอง?