Ruby pengecualian
Pengecualian dan eksekusi selalu dikaitkan. Jika Anda membuka file yang tidak ada, dan tidak benar menangani situasi, maka program Anda dianggap berkualitas rendah.
Jika pengecualian terjadi, program berhenti. penanganan eksepsi untuk semua jenis kesalahan yang mungkin terjadi selama eksekusi program, sehingga untuk mengambil tindakan yang tepat, dan tidak akan membiarkan program benar-benar berhenti.
Ruby menyediakan mekanisme sempurna untuk penanganan pengecualian. Kami dapat melampirkan kode yang mungkin melemparkan pengecualian, dan menggunakan klausapenyelamatanuntuk memberitahu Ruby jenis yang sempurna pengecualian untuk ditangani di blokmulai / akhir.
tatabahasa
begin #开始 raise.. #抛出异常 rescue [ExceptionType = StandardException] #捕获指定类型的异常 缺省值是StandardException $! #表示异常信息 $@ #表示异常出现的代码位置 else #其余异常 .. ensure #不管有没有异常,进入该代码块 end #结束
Untukmemulaisegala sesuatu daripenyelamatandilindungi. Jika selama pelaksanaan kode blok pengecualian terjadi, kontrol akan diteruskan antaraakhirdan blokpenyelamatan.
Untukmemulaiblok masing-masing klausapenyelamatan,Ruby dan pengecualian dilemparkan pada gilirannya untuk setiap perbandingan parameter. Jika penyelamatan klausul pengecualian penamaan dan pengecualian jenis dilempar oleh arus yang sama, atau kelas induk pengecualian, pertandingan itu berhasil.
Jika pengecualian tidak cocok dengan jenis tertentu dari kesalahan, kita dapat menggunakan klausalainsetelah semua klausulpenyelamatan.
contoh
#!/usr/bin/ruby begin file = open("/unexistant_file") if file puts "File opened successfully" end rescue file = STDIN end print file, "==", STDIN, "\n"
Contoh output di atas berjalan. Seperti yang Andalihat,STDIN gantifile,karenaterbukagagal.
#<IO:0xb7d16f84>==#<IO:0xb7d16f84>
Pernyataan penggunaanretry
Anda dapat menggunakan blokpenyelamatanuntuk menangkap pengecualian, dan kemudian menggunakan blok pernyataancoba lagimulaimulaidari awal.
tatabahasa
begin # 这段代码抛出的异常将被下面的 rescue 子句捕获 rescue # 这个块将捕获所有类型的异常 retry # 这将把控制移到 begin 的开头 end
contoh
#!/usr/bin/ruby begin file = open("/unexistant_file") if file puts "File opened successfully" end rescue fname = "existant_file" retry end
Berikut ini adalah alur proses:
- Pengecualian terjadi ketika dibuka.
- Skip to menyelamatkan. fname akan dipindahkan.
- Loncat ke awal mulai dengan coba lagi.
- file berhasil dibuka.
- Lanjutkan proses dasar.
Catatan: Jika file berganti nama tidak ada, kode pasukan ini upaya terbatas.Jadi penanganan eksepsi, gunakan hati-haticoba lagi.
Pernyataan penggunaankenaikan gaji
Anda dapat menggunakan pernyataankenaikanmelempar pengecualian. Metode berikut melempar pengecualian ketika Anda menelepon. Pesan kedua akan menjadi output.
tatabahasa
raise 或 raise "Error Message" 或 raise ExceptionType, "Error Message" 或 raise ExceptionType, "Error Message" condition
Bentuk pertama hanya kembali melempar pengecualian saat ini (jika tidak ada pengecualian saat dilemparkan RuntimeError a). Ini digunakan untuk menjelaskan sebelum masuk pengecualian pengecualian pengecualian handler.
Bentuk kedua menciptakan pengecualianRuntimeErrorbaru, pengaturan pesan untuk string yang diberikan. Setelah panggilan tumpukan untuk melemparkan pengecualian.
Bentuk ketiga parameter pertama untuk membuat pengecualian, kemudian mengatur pesan terkait sebagai parameter kedua.
Bentuk keempat dan bentuk ketiga adalah sama, Anda dapat menambahkan pernyataan bersyarat tambahan (misalnyakecuali)untuk melemparkan pengecualian.
contoh
#!/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.'
Jalankan contoh di atas output:
I am before the raise. I am rescued. I am after the begin block.
Lain demonstrasikenaikan gajicontoh penggunaan:
#!/usr/bin/ruby begin raise 'A test exception.' rescue Exception => e puts e.message puts e.backtrace.inspect end
Jalankan contoh di atas output:
A test exception. ["main.rb:4"]
Pastikanpenggunaan laporan
Kadang-kadang, terlepas dari apakah eksepsi dilemparkan, Anda perlu memastikan bahwa beberapa proses selesai pada akhir blok kode. Misalnya, Anda mungkin membuka file pada saat masuk, ketika Anda keluar blok, Anda perlu memastikan untuk menutup file.
memastikanklausul lakukan adalah ini. memastikan ditempatkan setelah klausa penyelamatan terakhir dan berisi blok kode blok terminasi selalu dieksekusi. Itu adalah normal untuk keluar blok, melempar dan menangani pengecualian apakah, apakah karena eksepsi tidak tertangkap berakhir, tak satu pun darihubungan ini,pastikan blok akan selalu dijalankan.
tatabahasa
begin #.. 过程 #.. 抛出异常 rescue #.. 处理错误 ensure #.. 最后确保执行 #.. 这总是会执行 end
contoh
begin raise 'A test exception.' rescue Exception => e puts e.message puts e.backtrace.inspect ensure puts "Ensuring execution" end
Jalankan contoh di atas output:
A test exception. ["main.rb:4"] Ensuring execution
Menggunakan pernyataanlain
Jikayang lainklausa disediakan, biasanya ditempatkan setelah klausapenyelamatan,sebelummemastikan.
badanlainklausul dijalankan hanya ketika tubuh kode tanpa membuang pengecualian.
tatabahasa
begin #.. 过程 #.. 抛出异常 rescue #.. 处理错误 else #.. 如果没有异常则执行 ensure #.. 最后确保执行 #.. 这总是会执行 end
contoh
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
Jalankan contoh di atas output:
I'm not raising exception Congratulations-- no errors! Ensuring execution
Gunakan $! Variable dapat menangkap pesan kesalahan dilemparkan.
Menangkap dan Lempar
meningkatkan dan mekanisme penyelamatan pengecualian dapat memberikan eksekusi bila terjadi kesalahan, kadang-kadang Anda perlu melompat dalam proses normal beberapa struktur sangat bersarang. Pada titik ini menangkap dan melempar berguna.
catchmendefinisikan nama yang diberikan (mungkin Symbol atau String) label sebagai blok. Blok dijalankan biasanya tahu pertemuan sepelemparan.
tatabahasa
throw :lablename #.. 这不会被执行 catch :lablename do #.. 在遇到一个 throw 后匹配将被执行的 catch end 或 throw :lablename condition #.. 这不会被执行 catch :lablename do #.. 在遇到一个 throw 后匹配将被执行的 catch end
contoh
Contoh berikut, jika pengguna jenis '!' Tanggapi setiap prompt, gunakan sepelemparan untuk mengakhiri interaksi dengan pengguna.
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: ") # .. # 处理信息 end promptAndGet("Name:")
Program di atas membutuhkan interaksi manusia, Anda dapat mencoba di komputer Anda. Jalankan contoh di atas output:
Name: Ruby on Rails Age: 3 Sex: ! Name:Just Ruby
kelas Exception
kelas standar Ruby dan modul dilemparkan. Semua kelas pengecualian membentuk sebuah hirarki, termasuk bagian atas kelas Exception batin. Lapisan berikutnya adalah tujuh jenis:
- interupsi
- NoMemoryError
- SignalException
- ScriptError
- StandardError
- SystemExit
Fatal adalah lapisan pengecualian lain, tetapi juru Ruby hanya menggunakannya secara internal.
ScriptError dan StandardError memiliki beberapa sub-kategori, tetapi di sini kita perlu tahu rincian ini. Yang paling penting adalah untuk membuat kelas pengecualian kita sendiri, mereka harus menjadi subclass dari kelas Exception atau turunannya.
Mari kita lihat sebuah contoh:
class FileSaveError < StandardError attr_reader :reason def initialize(reason) @reason = reason end end
Sekarang, lihat contoh berikut akan digunakan dalam pengecualian di atas:
File.open(path, "w") do |file| begin # 写出数据 ... rescue # 发生错误 raise FileSaveError.new($!) end end
Di sini, garis yang paling penting adalahmeningkatkanFileSaveError.new ($!). Kami menyebutnya menaikkan skematis pengecualian telah terjadi, itu berlalu contoh baru FileSaveError karena kelainan tertentu yang disebabkan oleh menulis data gagal.