Apa perbedaan - teknis, filosofis, konseptual, atau lainnya - antara
raise "foo"
dan
raise Exception.new("foo")
?
Apa perbedaan - teknis, filosofis, konseptual, atau lainnya - antara
raise "foo"
dan
raise Exception.new("foo")
?
Jawaban:
Secara teknis, yang pertama memunculkan RuntimeError dengan pesan disetel ke "foo"
, dan yang kedua memunculkan Pengecualian dengan pesan disetel ke "foo"
.
Secara praktis, ada perbedaan yang signifikan antara kapan Anda ingin menggunakan yang pertama dan kapan Anda ingin menggunakan yang kedua.
Sederhananya, Anda mungkin menginginkan file RuntimeError
bukan Exception
. Blok penyelamatan tanpa argumen akan menangkap RuntimeErrors
, tetapi TIDAK akan menangkap Exception
s. Jadi jika Anda meningkatkan Exception
kode Anda, kode ini tidak akan menangkapnya:
begin
rescue
end
Untuk menangkapnya, Exception
Anda harus melakukan ini:
begin
rescue Exception
end
Ini berarti bahwa dalam arti tertentu, an Exception
adalah kesalahan yang "lebih buruk" daripada a RuntimeError
, karena Anda harus bekerja lebih keras untuk memulihkannya.
Jadi yang Anda inginkan tergantung pada bagaimana proyek Anda melakukan penanganan kesalahannya. Misalnya, dalam daemon kami, loop utama memiliki penyelamatan kosong yang akan menangkap RuntimeErrors
, melaporkannya, dan kemudian melanjutkan. Tetapi dalam satu atau dua keadaan, kami ingin daemon benar-benar mati karena kesalahan, dan dalam hal ini kami memunculkan Exception
, yang langsung melewati "kode penanganan kesalahan normal" dan keluar.
Dan lagi, jika Anda menulis kode pustaka, Anda mungkin menginginkan a RuntimeError
, bukan an Exception
, karena pengguna pustaka Anda akan terkejut jika itu menimbulkan kesalahan yang rescue
tidak dapat ditangkap oleh blok kosong , dan itu akan membutuhkan waktu beberapa saat untuk menyadari alasannya.
Akhirnya, saya harus mengatakan bahwa itu RuntimeError
adalah subkelas dari StandardError
kelas, dan aturan sebenarnya adalah bahwa meskipun Anda dapat raise
semua jenis objek, kosong rescue
secara default hanya akan menangkap apa pun yang mewarisi dari StandardError
. Segala sesuatu yang lain harus spesifik.
StandardError
. Tidak harus lebih rumit dari beberapa baris class MissingArgumentsError < StandardError; end
.
raise
raise( string )
raise( exception [, string [, array ] ] )
Tanpa argumen, memunculkan pengecualian $!
atau RuntimeError
jika $!
nihil. Dengan satu String
argumen, ini memunculkan a RuntimeError
dengan string sebagai pesan. Jika tidak, parameter pertama harus nama Exception
kelas (atau objek yang mengembalikan Exception
pengecualian saat dikirim). Parameter opsional kedua menyetel pesan yang terkait dengan pengecualian, dan parameter ketiga adalah larik informasi panggilan balik. Pengecualian ditangkap oleh klausul penyelamatan begin...end
blok.
raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
RuntimeError < StandardError < Exception
[2] oleh karena itu, blok kode kedua itu akan menangkap Exception dan RuntimeError [3] menarik / aneh bahwa kenaikan dan penyelamatan "telanjang" bekerja dengan Exception tertentu [4] mungkin aturan praktisnya adalah menaikkan RuntimeError ke kode klien, tetapi meningkatkan dan menyelamatkan Pengecualian kustomnya sendiri di dalam kodenya sendiri?