Bukankah "jika (0 == nilai) ..." lebih berbahaya daripada kebaikan? [Tutup]

49

Ini adalah salah satu hal yang paling saya benci ketika saya melihatnya di kode orang lain. Saya tahu apa artinya dan mengapa beberapa orang melakukannya dengan cara ini ("bagaimana jika saya secara tidak sengaja meletakkan '=' sebagai gantinya?"). Bagi saya itu sangat seperti ketika seorang anak menuruni tangga menghitung langkah dengan keras.

Bagaimanapun, inilah argumen saya yang menentangnya:

  • Itu mengganggu aliran alami membaca kode program. Kita, manusia, mengatakan "jika nilai adalah nol" dan bukan "jika nol adalah nilai".
  • Kompiler modern memperingatkan Anda ketika Anda memiliki tugas dalam kondisi Anda, atau sebenarnya jika kondisi Anda hanya terdiri dari tugas itu, yang, ya, tetap terlihat mencurigakan
  • Anda tidak boleh lupa untuk melipatgandakan '=' ketika Anda membandingkan nilai jika Anda seorang programmer. Anda mungkin lupa untuk menempatkan "!" saat menguji ketidaksetaraan.
Mojuba
sumber
17
Saya tidak terlalu peduli untuk itu, tetapi cukup jauh di bawah daftar pribadi saya tentang kencing hewan peliharaan.
Adam Crossland
7
Dan terkadang programmer ketinggalan dobel '='. Ini adalah kesalahan yang mudah untuk dilakukan dan kesalahan yang sangat mudah untuk diabaikan.
agak
8
Bagaimana ini tidak konstruktif atau bukan pertanyaan nyata?
TheLQ
7
Ini ditutup jadi inilah pendapat singkat saya: bagaimana orang bisa ingat untuk menulis 0 == valuetetapi tidak ingat untuk menulis ==?? Maksud saya, astaga, jika Anda memikirkannya, mengapa tidak menulisnya dengan benar?
dr Hannibal Lecter
3
@ muntoo: Menurut kompiler, banyak hal yang "benar", saya tidak berpikir itu patokan yang sangat bagus.
dr Hannibal Lecter

Jawaban:

59

Ah, ya, "Yoda conditionals" ("Jika nilainya nol, jalankan kode ini Anda harus!"). Saya selalu menunjukkan siapa pun yang mengklaim mereka "lebih baik" pada alat-alat seperti serat (1). Masalah khusus ini telah dipecahkan sejak akhir 70-an. Sebagian besar bahasa modern bahkan tidak akan mengkompilasi ekspresi seperti if(x = 10), karena mereka menolak untuk memaksa hasil penugasan ke boolean.

Seperti yang orang lain katakan, itu jelas bukan masalah, tetapi itu sedikit memprovokasi disonansi kognitif.

TMN
sumber
32
+1 untuk "Yoda conditional". Saya benar-benar senang pada itu. :)
Bobby Tables
3
Sementara pemesanan baik - baik saja, saya keberatan dengan perbandingan ke nol, bukannya boolean,, if(!value).
SF.
1
Jadi, Anda menganggap penugasan di dalam suatu kondisi sebagai suatu kesalahan?
4
"Sebagian besar bahasa modern bahkan tidak akan mengkompilasi ini" Masalahnya muncul ketika Anda menggunakan bahasa yang secara diam-diam memaksa hasil penugasan ke boolean. Bahasa paling populer yang bisa saya pikirkan yang melakukan ini adalah JavaScript. Inilah sebabnya saya selalu menggunakan conditional yoda bahkan di Jawa sehingga saya tidak lupa melakukannya saat saya sedang menulis javascript. Saya beralih di antara keduanya cukup sering sehingga bisa (dan telah) menjadi masalah.
Sam Hasler
3
Adakah yang tahu kompiler yang tidak bisa dikompilasi if (0 == x)?
Kristopher Ives
56

Itu menjengkelkan karena memberlakukan pajak mental yang kecil, tetapi nyata.

Orang membaca dari kiri ke kanan dalam hampir semua bahasa pemrograman (dan sebagian besar bahasa alami).

Jika saya melihat 123 == x, cara saya menguraikannya secara mental adalah:

  • 123- terus? info tidak lengkap.
  • == - Nah, 123 adalah 123, mengapa mengujinya ...
  • x- ok, jadi itu yang kami khawatirkan. Hanya sekarang saya memiliki konteksnya.
  • Kembali ke pertimbangan ulang 123dan mengapa x dibandingkan dengan itu.

Ketika saya melihat x == 123parsing mental adalah:

  • x- Memberikan konteks, saya tahu tentang apa kondisinya. Saya dapat memilih untuk mengabaikan sisanya. Berdasarkan aliran sebelumnya saya punya ide bagus mengapa dan apa yang akan datang (dan terkejut jika itu berbeda).
  • == - Kupikir juga begitu.
  • 123 - Ya.

Gangguannya kecil (dalam contoh sederhana), tetapi saya selalu menyadarinya.

Menempatkan nilai pertama mungkin merupakan ide yang baik jika Anda ingin menarik perhatian padanya, misalnya if (LAUNCH_NUKES == cmd). Biasanya ini bukan niatnya.

dbkk
sumber
5
Persis. Dalam bahasa alami, konstanta selalu datang terakhir dengan alasan yang sama: jika cahayanya merah ...
mojuba
2
@mojuba Benar, ini hampir universal. Anehnya, ada beberapa bahasa alami di mana objek datang sebelum subjek (OVS / OSV order), tetapi mereka semua tidak jelas.
dbkk
1
Di sisi lain, sebagian dari kita cenderung membaca simbol sebelum variabel. Mereka lebih menarik. Jadi saya akan menguraikan =atau ==sebelum 123atau x, dan akhirnya tidak repot-repot menerjemahkan kode ke bahasa Inggris di kepala saya.
Izkata
Juga, sebagian besar kompiler akan memperingatkan jika diminta dengan benar, kecuali jika ada yang menggunakan kawat gigi ekstra, jadi ia mencoba menyelesaikan masalah yang tidak.
Deduplicator
47

Berbahaya? Tidak. Ini bekerja dengan baik.

Praktek yang Buruk? Luar biasa, terbaik. Ini pemrograman defensif yang sederhana.

Layak kehilangan tidur? Tidak

Wonko the Sane
sumber
8
Dan ketika saya membacanya, saya segera memahami kode yang bagi saya alasan paling penting untuk memperdebatkan gaya pengkodean. Saya sepenuhnya setuju, tidak layak kehilangan tidur.
Jeff Siver
17

Ini pada dasarnya adalah flaimbait.

Tidak, itu tidak lebih berbahaya daripada kebaikan. Sederhana.

Lebih banyak kata?

Argumen kompiler? Erm, ish, mungkin - jangan terlalu percaya pada penyusun untuk menyelamatkan Anda dari diri sendiri.

"Anda tidak boleh lupa" - juga duh - tidak ada tentu saja Anda tidak harus sementara aku lelah, aku sudah coding sepanjang hari saya harus menggunakan dua bahasa yang berbeda dan kadang-kadang, hanya kadang-kadang, menjadi manusia aku make kesalahan.

Inti dari perilaku semacam ini adalah sikapnya yang defensif, tidak ada di sana karena Anda berharap untuk membuat kesalahan lebih daripada Anda memiliki asuransi karena Anda berharap untuk crash ... tetapi jika Anda melakukannya dengan baik untuk dilindungi.

Susah dibaca? Anda mengeluh bahwa seorang programmer yang baik seharusnya memiliki == bawaan (yang membuat semua jenis asumsi yang buruk) tetapi programmer yang sama tidak dapat membaca 0 == nilai ??

Tidak ada salahnya, memiliki manfaat potensial, pertanyaan konyol, biarkan orang lain melakukannya jika mereka mau dan terus maju.

Murph
sumber
6
Saya pikir 0 == nilai dibaca tidak alami bagi mereka yang mempelajari cara aljabar sebelum mereka belajar pemrograman.
mojuba
4
Itu bukan intinya - ya, Anda benar itu tidak membaca dengan benar tetapi juga banyak dari apa yang kita, sebagai programmer, menulis tidak benar-benar menumpuk sebagai bahasa alami dan itu adalah masalah bagaimana Anda menafsirkan apa Anda lihat
Murph
4
Bravo .. Belum lagi fakta bahwa karena terbaca secara tidak wajar Anda cenderung memperhatikannya, karenanya menangkap kesalahan potensial.
mocj
7
@mocj - Oleh karena itu, kita semua harus kode semudah mungkin untuk memastikan bahwa orang yang membaca kode kita harus benar - benar membaca kode kita?
Kaz Dragon
6
@ Moj - Saya menghargai itu, tapi argumen Anda adalah bahwa "gagap otak" saat Anda membaca Yoda bersyarat adalah hal yang baik. Saya mengajukan pertanyaan bahwa, jika itu masalahnya, haruskah kita bertujuan untuk menulis semua kode sehingga kita menyebabkan "gagap otak"? Pertanyaan asli.
Kaz Dragon
11

Saya tidak akan menyebutnya berbahaya, tetapi itu menjengkelkan. Jadi tidak, saya tidak akan mengatakan itu.

Apa namanya
sumber
10

Saya tidak pernah merasakan keseluruhan 'bagaimana jika saya lupa a =?' pernah benar-benar memegang banyak berat badan. Ya, Anda mungkin membuat kesalahan ketik, tetapi kita semua membuat kesalahan ketik, tampaknya konyol untuk mengubah seluruh gaya pengkodean Anda karena Anda takut membuat kesalahan. Mengapa tidak membuat semua variabel Anda & fungsi semuanya huruf kecil tanpa tanda baca, karena Anda mungkin lupa untuk memanfaatkan sesuatu atau melupakan garis bawah suatu hari?

GSto
sumber
5
Itu bukan inti dari pertanyaan, intinya adalah "apakah itu berbahaya" - dan itu tidak. Iritasi yang sangat kecil paling buruk, tetapi tidak berbahaya.
Murph
1
Dalam bahasa yang dinamis - tentu saja, Anda dapat salah ketik simbol dan membuang waktu Anda nanti untuk mencari sumber bug Anda
mojuba
3
dengan segala hormat, ketika Anda menghabiskan larut malam (atau dua) dan menemukan sumber (dalam kode C ++) adalah = bukannya ==, itu akan membawa sedikit berat.
DevSolo
2
@DevSolo: Saya pikir itu harus benar-benar terjadi sekali atau dua kali dalam karir Anda, tetapi tidak lebih dari itu
mojuba
9

Beberapa orang menggunakannya untuk memperjelas apa yang dilakukan oleh kondisi. Misalnya:

Cara 1:

FILE *fp;

fp = fopen("foo.txt", "w+");
if (fp == NULL) {

Cara 2:

FILE *fp;

if (NULL == (fp = fopen("foo.txt", "w+"))) {

Beberapa orang merasa bahwa contoh kedua lebih ringkas, atau argumen pembalik menggambarkan titik ujian (bersyarat) sebelum ujian itu sendiri.

Sebenarnya, saya juga tidak keberatan. Saya punya hewan peliharaan saya kesal tentang gaya dan yang terbesar adalah inkonsistensi. Jadi, lakukan dengan cara yang sama, secara konsisten dan saya tidak keberatan membaca kode Anda.

Mencampurnya sampai ke titik di mana sepertinya enam orang yang berbeda dengan gaya khas mereka mengerjakannya sekaligus, saya menjadi sedikit kesal.

Pos Tim
sumber
4
Contoh kedua membuat saya berkata, "Ya?" Yang pertama jauh lebih mudah dibaca. Contoh yang bagus :)
Mateen Ulhaq
6

Bagi saya, itu adalah pengondisian sederhana. Sebagai seseorang yang belajar (di 90-an) C dan C ++, saya menjadi terbiasa dan masih menggunakannya, meskipun alasannya dikurangi.

Setelah Anda "dikondisikan" untuk melihat sisi kiri untuk "konstan", itu menjadi sifat kedua.

Saya juga hanya menggunakannya untuk kesetaraan (atau negated equivalence), bukan untuk lebih besar / kurang dari.

Saya setuju sepenuhnya dengan jawaban Wonko.

DevSolo
sumber
5

Satu kasus di mana saya merasa terbantu adalah di mana bagian variabel jika cukup panjang dan melihat nilai-nilai membuat kode lebih mudah dibaca. Bahasa namespace bertitik memiliki contoh terbaik ini.

Misalnya sesuatu yang saya kerjakan dengan sistem masuk tunggal memiliki situasi di mana Anda dapat memiliki dua sesi bersamaan jika jenis kesalahan tertentu terjadi dan dipulihkan dengan cara tertentu, jadi saya harus menambahkan pawang untuk itu yang ada di dalam jika itu tampak sesuatu seperti ini:

if (2 <= application.httpcontext.current.session["thenameofmysessiontoken"].items.count())

Harus diakui dalam contoh ini ada cara lain untuk melakukan ini, tetapi ini akan menjadi kasus di mana versi nomor-pertama berpotensi lebih mudah dibaca.

Tagihan
sumber
2
Saya pikir kata kunci di sini adalah "cara lain untuk melakukan ini";)
mojuba
dalam hal ini ya, tetapi dalam beberapa kasus ini masih merupakan hasil yang paling mudah dibaca. Satu-satunya poin saya adalah ada beberapa alasan yang sah untuk melakukan ini selain untuk memerangi bahasa atau perilaku dan tipe ide
Bill
Sejujurnya, saya mengalami kesulitan dengan kondisi Yoda untuk <= dan> =. Tanda == adalah masalah yang berbeda, karena di kepala saya, saya hanya bisa mengganti simbol, tetapi dalam kasus Anda, saya perlu mengingat bahwa jumlah () harus lebih besar dari atau sama dengan 2, dan itu agak menjengkelkan untuk diturunkan dari tanda yang lebih kecil atau sama.
Alex
3

Namun kesalahan terjadi. Dan kadang-kadang Anda menginginkan penugasan dalam operator loop di mana Anda mungkin memeriksa kesetaraan, atau setidaknya itu adalah praktik standar untuk menggunakannya.

Saya terus dengan itu. Saran yang saya ikuti (mungkin dari Kode Lengkap) adalah untuk menjaga apa yang seharusnya menjadi nilai yang lebih rendah di sebelah kiri dalam perbandingan. Saya mendiskusikan ini dengan seorang rekan sebelumnya dan dia pikir itu agak gila tapi saya sudah terbiasa dengannya.

Jadi saya akan mengatakan:

if ( 0 <= value )

Tetapi saya juga akan mengatakan:

if ( value <= 100 )

Kesetaraan saya akan cenderung untuk memeriksa dengan variabel di sebelah kiri, itu hanya lebih mudah dibaca.

glenatron
sumber
1
Saya terbiasa menggunakan if(y > x)semua waktu. Kecuali jika ysebuah konstanta.
Mateen Ulhaq
Saya dulu melakukannya dengan cara itu, tetapi begitu saya mendapat ide memiliki nilai terendah di sebelah kiri saya telah menemukan kode saya jauh lebih mudah dibaca sekilas.
glenatron