Latest web development tutorials

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.