Apa tujuan dari "!" dan "?" di akhir nama metode?

Jawaban:

160

Ini "hanya lapisan gula" agar terbaca, tetapi mereka memiliki arti yang sama:

  • Metode yang diakhiri dengan !melakukan beberapa perubahan permanen atau berpotensi berbahaya ; sebagai contoh:
    • Enumerable#sortmengembalikan versi objek yang diurutkan sambil Enumerable#sort!mengurutkannya di tempatnya.
    • Di Rails, ActiveRecord::Base#savemengembalikan false jika penyimpanan gagal, sementara ActiveRecord::Base#save!memunculkan pengecualian.
    • Kernel::exitmenyebabkan skrip keluar, sementara Kernel::exit!melakukannya segera, melewati penangan keluar apa pun.
  • Metode yang diakhiri dengan ?mengembalikan boolean , yang membuat aliran kode menjadi lebih intuitif seperti kalimat - if number.zero?dibaca seperti "jika angkanya nol", tetapi if number.zeroterlihat aneh.

Dalam contoh Anda, name.reversemengevaluasi ke string terbalik, tetapi hanya setelah name.reverse!baris namevariabel benar-benar berisi nama terbalik. name.is_binary_data?Sepertinya "apakah namedata biner?".

jtbandes
sumber
22
Satu catatan penting adalah bahwa Anda hanya boleh memiliki metode bang jika Anda juga memiliki metode non-bang yang sesuai. Ledakan digunakan untuk membedakan versi yang "lebih mengejutkan" dari metode yang "kurang mengejutkan". Jika Anda hanya memiliki satu metode, maka tidak perlu membedakan, dan Anda tidak boleh menamainya dengan keras. Lihat Array#clear, misalnya. Ini menghapus array. Menghapus array secara alami akan memutasinya. Tidak ada yang mengejutkan tentang itu, namanya sudah menjelaskan, oleh karena itu: tidak ada ledakan. Lihat ruby-forum.com/topic/176830#773946 .
Jörg W Mittag
2
Menambahkan apa yang @ JörgWMittag nyatakan, menurut Ruby Style Guide : Nama metode yang berpotensi berbahaya (yaitu metode yang mengubah diri atau argumen, exit! (Tidak menjalankan finalizer seperti exit), dll.) Harus diakhiri dengan tanda seru jika ada versi aman dari metode berbahaya tersebut .
Tod Birdsall
2
Hati-hati, ini tidak selalu terjadi. Misalnya, Ruby Array # concat docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat . Di mana Anda bisa terbakar parah adalah sesuatu seperti MyActiveRecordModel.column_names.concat (...). Sebagai gantinya, Anda harus mengkloningnya sebelum melakukan concat.
wintondeshong
8

Di Ruby, ?artinya metode tersebut akan mengembalikan boolean dan !memodifikasi objek yang dipanggil. Mereka ada untuk meningkatkan keterbacaan saat melihat kode.

J Lundberg
sumber
5

Berbeda dengan - saya kira - mayoritas bahasa pemrograman ...

Ruby, metode diperbolehkan diakhiri dengan tanda tanya atau tanda seru.

Menurut konvensi, metode yang menjawab pertanyaan (yaitu Array # empty? Mengembalikan nilai true jika penerima kosong) diakhiri dengan tanda tanya.

Metode yang berpotensi "berbahaya" (yaitu metode yang mengubah diri atau argumen, keluar! Dll.) Dengan konvensi diakhiri dengan tanda seru.

Dari: http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/ , Nama metode Bagian Lucu

miku
sumber
1
Juga metode yang diakhiri dengan ?disebut metode predikat.
Waseem
1

Hati-hati, ini tidak selalu terjadi. Ambil contoh, Ruby Array # concat http://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat .

Di mana Anda bisa terbakar parah adalah sesuatu seperti MyActiveRecordModel.column_names.concat([url]). Panggilan selanjutnya yang terkait dengan MyActiveRecordModel akan mencoba mencari kolom 'url' untuk MyActiveRecordModel dan melempar.

Sebagai gantinya, Anda harus mengkloningnya sebelum melakukan concat. Untungnya test suite saya menangkap yang ini, tapi .. perhatian!

wintondeshong
sumber