ยกเว้นทับทิม
ข้อยกเว้นและการดำเนินการมีการเชื่อมโยงเสมอ ถ้าคุณเปิดไฟล์ที่ไม่อยู่และไม่ถูกต้องจัดการกับสถานการณ์แล้วโปรแกรมของคุณจะถือเป็นของที่มีคุณภาพต่ำ
หากเกิดข้อยกเว้นโปรแกรมก็จะหยุด การจัดการข้อยกเว้นสำหรับทุกประเภทของข้อผิดพลาดที่อาจเกิดขึ้นระหว่างการทำงานของโปรแกรมเพื่อที่จะดำเนินการที่เหมาะสมและจะไม่ให้โปรแกรมหยุดสมบูรณ์
ทับทิมให้เป็นกลไกที่สมบูรณ์แบบสำหรับการจัดการข้อยกเว้นเราสามารถแนบรหัสที่อาจโยนข้อยกเว้นและใช้คำสั่งกู้ภัยที่จะบอกทับทิมชนิดที่สมบูรณ์แบบของข้อยกเว้นที่จะจัดการในการเริ่มต้นบล็อกปลาย/
ไวยากรณ์
begin #开始 raiseth #抛出异常 rescue [ExceptionType = StandardException] #捕获指定类型的异常 缺省值是StandardException $! #表示异常信息 $@ #表示异常出现的代码位置 else #其余异常 th ensure #不管有没有异常,进入该代码块 end #结束
ในการเริ่มต้นทุกอย่างจากกู้ภัยได้รับการคุ้มครองหากในระหว่างการดำเนินการของข้อยกเว้นการป้องกันรหัสที่เกิดขึ้นการควบคุมจะถูกส่งผ่านระหว่างปลายและกู้ภัยบล็อก
สำหรับการเริ่มต้นบล็อกแต่ละข้อกู้ภัยทับทิมและข้อยกเว้นโยนในการเปิดแต่ละเปรียบเทียบพารามิเตอร์หากข้อกู้ภัยตั้งชื่อข้อยกเว้นและข้อยกเว้นประเภทโยนโดยปัจจุบันเดียวกันหรือเป็นระดับผู้ปกครองของข้อยกเว้นการแข่งขันประสบความสำเร็จ
หากยกเว้นไม่ตรงกับใด ๆของชนิดที่ระบุข้อผิดพลาดของเราสามารถใช้ข้ออื่นหลังจากข้อกู้ภัยทั้งหมด
ตัวอย่าง
#!/usr/bin/ruby begin file = open("/unexistant_file") if file puts "File opened successfully" end rescue file = STDIN end print file, "==", STDIN, "\n"
ตัวอย่างของการส่งออกดังกล่าวข้างต้นที่กำลังทำงานในขณะที่คุณสามารถดูSTDINแทนแฟ้มเพราะเปิดล้มเหลว
#<IO:0xb7d16f84>==#<IO:0xb7d16f84>
คำสั่งการใช้งานลองใหม่อีกครั้ง
คุณสามารถใช้บล็อกกู้ภัยที่จะจับข้อยกเว้นและจากนั้นใช้คำสั่งบล็อกลองใหม่อีกครั้งเริ่มเริ่มต้นจากจุดเริ่มต้น
ไวยากรณ์
begin # 这段代码抛出的异常将被下面的 rescue 子句捕获 rescue # 这个块将捕获所有类型的异常 retry # 这将把控制移到 begin 的开头 end
ตัวอย่าง
#!/usr/bin/ruby begin file = open("/unexistant_file") if file puts "File opened successfully" end rescue fname = "existant_file" retry end
ต่อไปนี้คือการไหลของกระบวนการ:
- ข้อยกเว้นเกิดขึ้นเมื่อเปิด
- ข้ามไปช่วยเหลือ fname ได้รับพระราชเสาวนีย์
- ข้ามไปที่จุดเริ่มต้นเริ่มต้นด้วยการลองใหม่อีกครั้ง
- แฟ้มถูกเปิดประสบความสำเร็จ
- ดำเนินการต่อกระบวนการพื้นฐาน
หมายเหตุ: หากไฟล์เปลี่ยนชื่อไม่ได้อยู่รหัสกองกำลังนี้จะพยายามไม่ จำกัดดังนั้นการจัดการข้อยกเว้นให้ใช้ความระมัดระวังลองใหม่อีกครั้ง
คำสั่งการใช้งานที่เพิ่มขึ้น
คุณสามารถใช้คำสั่งยกพ่นยกเว้นวิธีการต่อไปพ่นยกเว้นเมื่อคุณเรียก ข้อความที่สองจะถูกส่งออก
ไวยากรณ์
raise 或 raise "Error Message" 或 raise ExceptionType, "Error Message" 或 raise ExceptionType, "Error Message" condition
รูปแบบครั้งแรกเพียงแค่โยนข้อยกเว้นปัจจุบัน (ถ้ามีจะไม่มีข้อยกเว้นในปัจจุบันจะโยน Runtimeerror ก) นี้จะใช้เพื่ออธิบายก่อนยกเว้นที่เข้ามาดำเนินการยกเว้นข้อยกเว้น
รูปแบบที่สองสร้างข้อยกเว้นRuntimeerrorใหม่, การตั้งค่าข้อความสตริงที่กำหนด หลังจากที่โทรสแต็คที่จะโยนข้อยกเว้น
รูปแบบที่สามของพารามิเตอร์แรกที่จะสร้างข้อยกเว้นจากนั้นตั้งค่าข้อความที่เกี่ยวข้องเป็นพารามิเตอร์ที่สอง
รูปแบบที่สี่และรูปแบบที่สามคือการที่คล้ายกันคุณสามารถเพิ่มงบเงื่อนไขใด ๆ เพิ่มเติม(เช่นเว้นแต่)เพื่อโยนข้อยกเว้น
ตัวอย่าง
#!/usr/bin/ruby begin puts 'I am before the raise.' raise 'An error has occurred.' puts 'I am after the raise.' rescue puts 'I am rescued.' end puts 'I am after the begin block.'
เรียกเอาท์พุทตัวอย่างข้างต้นคือ
I am before the raise. I am rescued. I am after the begin block.
อีกตัวอย่างการใช้งานการสาธิตการเพิ่ม:
#!/usr/bin/ruby begin raise 'A test exception.' rescue Exception => e puts e.message puts e.backtrace.inspect end
เรียกเอาท์พุทตัวอย่างข้างต้นคือ
A test exception. ["main.rb:4"]
ให้แน่ใจว่าการใช้งบ
บางครั้งไม่ว่าจะยกเว้นจะโยนคุณจะต้องให้แน่ใจว่ากระบวนการบางอย่างจะแล้วเสร็จในปลายป้องกันรหัส ตัวอย่างเช่นคุณอาจจะเปิดไฟล์ในช่วงเวลาของรายการเมื่อคุณออกจากบล็อกคุณจะต้องให้แน่ใจว่าจะปิดแฟ้ม
ให้แน่ใจว่าข้อที่จะทำนี้ให้แน่ใจว่าวางอยู่หลังข้อกู้ภัยที่ผ่านมาและมีการป้องกันรหัสบล็อกการเลิกจ้างจะถูกดำเนินการอยู่เสมอ มันเป็นเรื่องปกติที่จะออกจากบล็อกโยนและจัดการกับข้อยกเว้นว่าไม่ว่าจะเป็นเพราะข้อยกเว้น uncaughtยุติไม่มีความสัมพันธ์เหล่านี้ให้แน่ใจว่าบล็อกมักจะเรียกใช้
ไวยากรณ์
begin #th 过程 #th 抛出异常 rescue #th 处理错误 ensure #th 最后确保执行 #th 这总是会执行 end
ตัวอย่าง
begin raise 'A test exception.' rescue Exception => e puts e.message puts e.backtrace.inspect ensure puts "Ensuring execution" end
เรียกเอาท์พุทตัวอย่างข้างต้นคือ
A test exception. ["main.rb:4"] Ensuring execution
การใช้คำสั่งอื่น
หากข้ออื่น ๆที่มีให้ก็มักจะวางอยู่หลังประโยคช่วยเหลือก่อนที่จะให้แน่ใจว่าการใด ๆ
ข้ออื่นของร่างกายจะถูกดำเนินการเฉพาะเมื่อร่างกายของรหัสโดยไม่ต้องโยนข้อยกเว้น
ไวยากรณ์
begin #th 过程 #th 抛出异常 rescue #th 处理错误 else #th 如果没有异常则执行 ensure #th 最后确保执行 #th 这总是会执行 end
ตัวอย่าง
begin # 抛出 'A test exception.' puts "I'm not raising exception" rescue Exception => e puts e.message puts e.backtrace.inspect else puts "Congratulations-- no errors!" ensure puts "Ensuring execution" end
เรียกเอาท์พุทตัวอย่างข้างต้นคือ
I'm not raising exception Congratulations-- no errors! Ensuring execution
ใช้ $! ตัวแปรสามารถจับข้อผิดพลาดโยน
จับและโยน
เพิ่มและกลไกการช่วยเหลือยกเว้นสามารถให้ขึ้นการดำเนินการเมื่อเกิดข้อผิดพลาดบางครั้งคุณต้องกระโดดในกระบวนการปกติของโครงสร้างที่ซ้อนกันอย่างลึกซึ้งบาง ที่จับจุดนี้และโยนเข้ามามีประโยชน์
จับกำหนดให้ชื่อ(อาจจะเป็นสัญลักษณ์หรือสตริง) ฉลากเป็นบล็อก บล็อกจะถูกดำเนินการตามปกติรู้พบโยน
ไวยากรณ์
throw :lablename #th 这不会被执行 catch :lablename do #th 在遇到一个 throw 后匹配将被执行的 catch end 或 throw :lablename condition #th 这不会被执行 catch :lablename do #th 在遇到一个 throw 后匹配将被执行的 catch end
ตัวอย่าง
ตัวอย่างต่อไปนี้ถ้าผู้ใช้ '' ตอบสนองต่อพรอมต์ใด ๆ ใช้โยนที่จะยุติการมีปฏิสัมพันธ์กับผู้ใช้
def promptAndGet(prompt) print prompt res = readline.chomp throw :quitRequested if res == "!" return res end catch :quitRequested do name = promptAndGet("Name: ") age = promptAndGet("Age: ") sex = promptAndGet("Sex: ") # th # 处理信息 end promptAndGet("Name:")
โปรแกรมดังกล่าวข้างต้นต้องมีปฏิสัมพันธ์ของมนุษย์ที่คุณสามารถลองบนคอมพิวเตอร์ของคุณ เรียกเอาท์พุทตัวอย่างข้างต้นคือ
Name: Ruby on Rails Age: 3 Sex: ! Name:Just Ruby
ระดับข้อยกเว้น
เรียนมาตรฐานทับทิมและโมดูลโยน ทุกชั้นเรียนยกเว้นรูปแบบลำดับชั้นรวมถึงด้านบนของชั้นยกเว้นชั้นใน ชั้นต่อไปคือเจ็ดประเภทที่แตกต่างกัน
- ขัดจังหวะ
- NoMemoryError
- SignalException
- ScriptError
- StandardError
- SystemExit
ร้ายแรงเป็นชั้นของอีกยกเว้น แต่ล่ามทับทิมใช้เฉพาะภายใน
ScriptError และ StandardError มีบางหมวดย่อย แต่ที่นี่เราจำเป็นต้องรู้รายละเอียดเหล่านี้ สิ่งที่สำคัญที่สุดคือการสร้างชั้นยกเว้นของเราเองที่พวกเขาจะต้องเป็น subclass ของข้อยกเว้นชั้นเรียนหรือลูกหลานของตน
ลองดูที่ตัวอย่าง:
class FileSaveError < StandardError attr_reader :reason def initialize(reason) @reason = reason end end
ตอนนี้ดูตัวอย่างต่อไปนี้จะถูกนำมาใช้ในข้อยกเว้นด้านบน:
File.open(path, "w") do |file| begin # 写出数据 th. rescue # 发生错误 raise FileSaveError.new($!) end end
นี่สายสำคัญที่สุดคือการยกระดับFileSaveError.new ($!) เราเรียกระดมแผนผังยกเว้นเกิดขึ้นก็ผ่านตัวอย่างใหม่ FileSaveError เนื่องจากความผิดปกติเฉพาะที่เกิดจากการเขียนข้อมูลล้มเหลว