Mengapa variabel yang tidak digunakan adalah masalah seperti itu?

10

Saya sedang membersihkan peringatan variabel yang tidak digunakan suatu hari, dan saya mulai merenungkan, apa sebenarnya masalah tentang mereka?

Bahkan, beberapa dari mereka bahkan membantu dalam debugging (mis. Memeriksa detail pengecualian, atau memeriksa nilai pengembalian sebelum dikembalikan).

Saya tidak dapat menemukan risiko nyata yang sebenarnya dalam memilikinya ..

Contohnya

Maksud saya bukan baris yang membutuhkan waktu dari perhatian programmer lain, seperti:

int abc = 7;

Itu adalah redundansi dan gangguan yang jelas. Maksud saya hal-hal seperti:

try {
    SomeMethod();
} catch (SomeException e) {
    // here e is unused, but during debug we can inspect exception details
    DoSomethingAboutIt();
}
Ter
sumber
31
Maksud Anda selain fakta bahwa programmer yang datang setelah Anda harus menghabiskan waktu untuk mencari tahu mengapa mereka ada di sana?
Robert Harvey
1
Contoh Anda tidak berbahaya, tetapi saya belum pernah melihat kasus seperti itu disebut sebagai "variabel yang tidak digunakan". Dari mana peringatan Anda berasal?
Jacob Raihle
9
Yah, rettidak terpakai.
Robert Harvey
4
Anda menulis " Maksud saya hal-hal seperti catch (SomeException e) " - Anda berpura-pura ada kasus lain yang serupa. Cerahkan saya, yang mana? Saya bertanya karena di C # atau C ++, saya kesulitan menemukan situasi yang berbeda untuk kasus Anda.
Doc Brown

Jawaban:

5

Menurut kerangka yang Anda berikan, sulit untuk membantah variabel - variabel itu sendiri:

try {
    SomeMethod();
} catch (SomeException e) {
// here e is unused, but during debug we can inspect exception details
DoSomethingAboutIt();
}

Ambil contoh ini. Anda menangkap pengecualian dan (mungkin) memiliki kode yang berhubungan dengan pengecualian dengan cara yang benar. Fakta bahwa Anda tidak menggunakan instance sebenarnya dari pengecualian tidak ada salahnya, baik untuk aliran kode maupun untuk dimengerti.

Tetapi yang membuat saya berpikir adalah ketika Anda menulis tentang legitimasi »variabel yang tidak digunakan«

Bahkan, beberapa dari mereka bahkan membantu dalam debugging

Itu bukan tujuan penulisan kode: harus di-debug nanti. Untuk mencegah kesalahpahaman, saya harus mengatakan, bahwa saya sangat sadar, bahwa seringkali Anda harus memperbaiki kode Anda; dan terkadang debugging adalah solusinya. Tetapi seharusnya tidak menjadi yang pertama, apa yang terlintas dalam pikiran Anda, ketika menulis kode, bahwa Anda meninggalkan "anchor points", yang tujuan utamanya adalah untuk mempermudah proses debug.

SomeClass Func() {
    // ...stuff...
    var ret = FinalComputationResult(thing, foo, bar);
    // ret is unused, but while debugging allows checking return value.
    return ret;
}

Di sini tergantung seberapa kompleks stuffdan bagaimana hal itu terkait dengan nilai, yang dikembalikan.

Sebagai "Aturan Emas", saya akan mengatakan yang berikut:

Jika itu membantu memahami tujuan kode, tidak apa-apa untuk meningkatkan redundansi dalam kode Anda

atau dengan kata lain:

Tulis kode Anda sebagai bebas redundansi yang diperlukan untuk memahami nanti dengan mudah, apa yang dilakukan kode

Yang menghasilkan: Sebagian besar waktu, Anda harus menghapus "debug" -variables .

Thomas Junk
sumber
19

Masalah terbesar adalah kejelasan . Jika kode Anda memiliki banyak sampah asing di dalamnya, dan saya menjaga kode Anda, saya harus mencari tahu apa yang semuanya lakukan.

Apakah variabel itu pernah digunakan untuk apa pun? Mungkin Anda melakukan operasi di atasnya, tetapi tidak pernah menggunakan nilainya untuk sesuatu. Cukup menambah variabel tidak berarti variabel melayani tujuan jika Anda tidak pernah membacanya (kembali, masukkan ke ekspresi lain, dkk).

Namun: jika suatu variabel memiliki tujuan dan dinamai dengan tepat, itu tidak mengurangi kode secara keseluruhan.

Dengan memberikan contoh dalam pertanyaan Anda yang diperbarui dan beberapa yang lain, saya memikirkan:

  • Memiliki fungsi yang memanggil fungsi lain, menyimpan hasilnya, mencatatnya, lalu mengembalikannya cukup singkat dan jelas.

  • Memisahkan pernyataan dengan banyak ekspresi menjadi banyak pernyataan (mis. Memecah perhitungan yang panjang dan rumit menjadi banyak pernyataan dengan beberapa variabel perantara) dapat membuat kode lebih jelas meskipun lebih bertele-tele. Dengan lebih sedikit informasi untuk diproses pada satu waktu, otak dapat lebih mudah memahami apa yang sedang terjadi.

  • Tidak menggunakan pengecualian benar-benar baik: sebagian besar bahasa mengharuskan untuk menentukan pengecualian yang ditangkap termasuk memberikan nama variabel untuk digunakan dalam catchblok. Tidak ada jalan lain dalam hal ini dalam banyak bahasa populer dan pemrogram terbiasa dengannya.

Jika saya perlu menghabiskan waktu mencari tahu elemen kode apa yang memiliki tujuan dan yang hanya membuang-buang waktu saya, produktivitas saya menurun. Namun, jika kode tersebut cukup ringkas dan variabel-variabelnya diberi nama dengan baik bahkan ketika mereka tampak tidak cocok pada awalnya, ini mengurangi risiko membuang-buang waktu yang tidak perlu meninjau kode untuk memahaminya.

Kode buruk dengan variabel asing, blok kosong, dan kode mati adalah salah satu cara pengembang mendapatkan reputasi buruk di kantor: "Saya memperbaiki bug dalam kode Snowman. Saya menghabiskan dua jam mencari tahu apa fungsi itu lakukan, dan memperbaiki tiga puluh detik bug! Snowman mengerikan dalam pemrograman! " Tetapi jika kode memiliki tujuan dan ditulis dengan cara yang jelas, itu baik-baik saja.


sumber
9
+1 untuk "Snowman mengerikan dalam pemrograman." Saya selalu curiga. Bagaimana Anda bisa menjadi programmer yang baik ketika jari-jari Anda selalu meleleh?
Robert Harvey
Lihat hasil edit saya - maksud saya bukan hanya variabel yang dibuat dengan tiba-tiba tanpa tujuan, hanya variabel yang dapat membantu di sana-sini selama debug, atau hanya dihasilkan oleh salah satu alat otomatis seperti catch blocks.
Tar
1
@Tar yang mengubah seluruh pertanyaan - edit yang masuk.
Perhatikan bahwa dalam daftar berpoin ketika Anda melakukan ini, dua yang pertama cenderung tidak benar-benar menghasilkan peringatan (Saya belum pernah melihat bahasa yang menghasilkan peringatan dalam kasus seperti itu). Untuk kasus ketiga, bahasa apa pun yang memerlukan pengecualian diberi pengenal tidak memiliki peringatan untuk itu, dan bahasa apa pun yang menghasilkan peringatan untuk itu tidak mengharuskan untuk memiliki pengenal (sekali lagi, yang saya kenal dengan bagaimanapun).
Servy
2
Melihat sejarah revisi saya tidak melihat indikasi pertanyaan yang berubah secara mendasar. Sejauh kode OP berjalan, dua yang pertama akan menghasilkan peringatan dalam C # (yang terlihat sebagai bahasa yang digunakan). Contoh ketiga tidak akan menghasilkan peringatan. Komentar pada pertanyaan juga menunjukkan bahwa mereka secara khusus ditunjukkan dalam peringatan kompiler, dan ketika Robert menunjukkan bahwa contoh ketiga tidak menghasilkan peringatan, penulis mengakui bahwa itu adalah contoh buruk untuk pertanyaan mereka.
Servy
5

Variabel yang tidak digunakan yang tidak memiliki tujuan yang jelas adalah bau kode dalam pandangan saya. Paling-paling, mereka bisa menjadi gangguan - mereka menambah kebisingan umum dalam modul.

Kasus terburuk adalah bahwa coders berikutnya menghabiskan waktu untuk mencari tahu apa yang seharusnya dilakukan dan bertanya-tanya apakah kode tersebut lengkap. Bantulah diri Anda sendiri (dan semua orang) dan singkirkan.

Robbie Dee
sumber
1
Apa itu "bug" dalam pandangan Anda? Variabel yang tidak digunakan tidak menghasilkan hasil yang tidak terduga dan salah per se, yang mana sebagian besar orang akan memenuhi syarat sebagai bug.
Harris
5
Mengapa variabel tidak digunakan? Sangat mungkin karena seharusnya digunakan, tetapi variabel lain digunakan bukan karena kesalahan. Anda mendapatkan peringatan kompiler, dan Anda memperbaikinya dan memperbaiki bug pada saat yang sama. Masalahnya adalah jika Anda memiliki programmer yang tidak disiplin yang membuat kekacauan, Anda tidak dapat menemukan di mana peringatan seperti itu menunjukkan bug dan di mana itu hanya menunjukkan programmer yang berantakan.
gnasher729
@ HarrisWeinstein Diberikan penguji dan devs bahkan tidak bisa setuju apa bug sebagian besar waktu, saya akan memarkir itu untuk saat ini. Cukuplah untuk mengatakan itu adalah kekurangan dalam kode - dan mungkin dieksekusi karena akan mengambil ruang. Diakui, bukan masalah terbesar di dunia tetapi di atas sana dengan kotak kesalahan ejaan komentar dan kode komentar. Ini adalah cruft yang tidak menambahkan apa pun sehingga harus dihapus. Kode yang terlihat bagus menginspirasi kepercayaan diri. Saya pikir kutipan ini juga tepat dan mencakup proses refactoring dengan baik.
Robbie Dee
Jika Anda menggunakan bahasa yang dinamis, memberikan nilai some_varsaat sisa kode digunakan someVarhampir dijamin sebagai bug. Ini mungkin bukan masalah di Java atau C tetapi dapat dengan mudah memecahkan beberapa Python.
Sean McSomething
1
@ThomasJunk Itu mungkin istilah yang lebih baik untuk itu - terima kasih. Saya akan menyesuaikan jawaban saya sesuai dengan itu.
Robbie Dee
5

Variabel yang tidak digunakan membuat maksud kode Anda tidak jelas. Ini buruk karena meskipun penampilan, kode terutama ditulis untuk orang untuk membaca, bukan untuk komputer .

Orang lain telah menunjukkan bahwa membangun nilai dan tidak menggunakannya membingungkan orang lain yang harus membaca dan bekerja dengan kode Anda. Namun, dalam pandangan saya bahaya yang lebih besar adalah pada diri Anda sendiri .

Variabel yang tidak terpakai mungkin disengaja, atau mungkin merupakan pengawasan yang menunjuk pada cacat. Misalnya, Anda mungkin salah ketik nama dan menyimpan nilai di satu tempat ketika Anda berpikir Anda akan menyimpannya di tempat lain. Program yang dihasilkan bisa berjalan dengan baik tetapi diam-diam memberikan hasil yang salah.

Menganalisis aliran data dapat membantu Anda menemukan kesalahan seperti itu dan banyak lainnya. Oleh karena itu membayar untuk menulis kode Anda sedemikian rupa sehingga segala sesuatu yang ditunjukkan oleh penganalisa aliran data sebagai anomali sebenarnya adalah sebuah bug. Bantuan otomatis dalam mencegah bug sangat berharga; banyak orang berpikir, "Oh, aku tidak butuh bantuan, aku tidak akan semudah itu", tetapi sejauh ini semua orang yang aku temui yang berpikir itu salah.

Kilian Foth
sumber
2

Ada gaya pengkodean yang melibatkan penugasan sengaja apa pun yang (atau mungkin menjadi) menarik untuk variabel untuk tujuan khusus dengan mudah melihatnya dalam debugger. Ini sangat berguna untuk kode yang terlihat seperti:

return foo(bar(), baz(wot(12), wombat(&badger)));

Bahkan dengan nama-nama yang agak lebih baik untuk fungsi-fungsi tersebut, bisa lebih mudah untuk mengetahui apa yang salah dalam panggilan ke foo ketika dituliskan sebagai:

auto awombat = wombat(&badger);
auto awot = wot(12);
auto abaz = baz(awot, abadger);
auto abar = bar();
auto afoo = foo(abar, abaz);
return afoo;

Saya belum bekerja dengan orang-orang yang mempraktekkan ini sebagai konfigurasi default, tetapi menulis ulang sepotong kode yang dengan keras kepala menolak untuk masuk akal dalam bentuk penugasan tunggal dapat membuatnya lebih mudah untuk mengetahui apa yang terjadi di bawah debugger. Kami selalu mengembalikan kode tersebut ke format "cantik" yang ringkas setelahnya, tetapi saya ingin tahu apakah itu kesalahan.

Alternatifnya adalah berjalan naik dan turun tumpukan dan berharap Anda tidak melangkah terlalu jauh, atau menggunakan debuggers reversibel (jarang sekali).

Ini bukan strategi yang populer, tetapi karena ini membantu saya mengatasi beberapa bug yang tidak masuk akal, saya tidak berpikir itu harus dihapuskan secara intrinsik buruk.

Jon Chesterfield
sumber
Sementara saya mungkin tidak akan pergi sejauh yang Anda lakukan saya menemukan bentuk "cantik" pertama Anda terlalu kompak.
Loren Pechtel
Kecuali bahwa tidak ada variabel tunggal yang tidak digunakan dalam kode Anda.
Florian F
Sisi positifnya, jika Anda mendapat peringatan tentang variabel yang tidak digunakan, Anda akan tahu bahwa di suatu tempat dalam transformasi itu Anda melakukan kesalahan besar. Yang mana akan mudah diperbaiki.
gnasher729
1

Untuk orang-orang yang memasukkan kode tes unit mereka dalam proyek atau modul yang sama dengan kode "asli" mereka, bidang yang tidak digunakan , seperti metode objek, adalah sinyal kuat bahwa tes unit Anda tidak menguji semuanya. Ini meningkatkan kemungkinan pengembang akan mencoba menggunakan bidang atau metode yang saat ini tidak digunakan, dan mengalami bug yang tidak tertangkap sampai saat itu.

Variabel yang tidak digunakan dalam subrutin atau metode yang agak nontrivial dapat menunjukkan bahwa programmer bermaksud untuk menggunakannya, tetapi menggunakan variabel lain secara tidak sengaja (misalnya, setelah membersihkan setelah operasi copy-paste).

Variabel yang tidak digunakan dalam subrutin yang lebih sepele mungkin merupakan sampah yang tidak perlu, seperti yang dijawab orang lain. Kadang-kadang, itu digunakan dalam pernyataan remah roti yang saat ini dikomentari:

SomeObject tmp = someMethod();
// printDebugInfoAbout (tmp);

... jelas bagi bola mata bahwa itu digunakan di sana, dan hanya di sana (yaitu someMethodmemiliki efek samping yang penting), tetapi IDE tidak tahu itu, dan menghapus variabel itu lebih banyak masalah daripada nilainya. Saya sementara menggunakan penekan peringatan dalam kasus seperti itu.

Paul Brinkley
sumber
1
Saya bertanya-tanya dalam keadaan apa Anda ingin berkomentar-kode keluar untuk repositori Anda. Tetapi situasi serupa muncul ketika menggunakan kompilasi bersyarat (seperti ketika menggunakan assertmakro di C atau C ++). Peringatan variabel yang tidak digunakan memang bisa menjadi gangguan di sana dan menekannya adalah respons paling masuk akal, jika Anda bertanya kepada saya.
5gon12eder
1
Saya telah mengedit jawaban saya, menambahkan contoh kasar tentang apa yang saya lihat di masa lalu. Blok mungkin dijalankan berkali-kali, dan ada sesuatu yang mengumpulkan semua info debug dalam log untuk dianalisis saat melacak masalah, tetapi pencetakan lambat dan biasanya dimatikan. Saya bisa mengganti baris pertama dengan someMethoddan kehilangan info dari mana tmpasalnya. Atau saya bisa melakukan versi bersih dan lupa bahwa beberapa versi masa lalu memiliki remah roti yang berguna (dan tidak memiliki kode yang diperlukan ditambahkan di versi kemudian). ... Saya sudah mencari tradeoff yang ideal untuk waktu yang lama sekarang.
Paul Brinkley
Saya melihat. Rupanya, bahasa pilihan Anda tidak memiliki pra-prosesor. ;-)
5gon12eder
Saat ini, ya. :-) Meskipun harus adil, saya telah melihat hal-hal yang sama di C dan C ++, dan juga tidak mudah untuk menyingkirkan variabel yang tidak digunakan dalam kasus-kasus itu, baik (quasi-appendices?). ... Fakta bahwa proyek C / C ++ besar terakhir saya dilakukan pada saat IDE tidak ada (peringatan kompiler diperlukan untuk menjalankan "gcc -pedantic") juga tidak membantu.
Paul Brinkley
0

Sangat mudah ketika Anda menulis kode untuk mencampur dua variabel. Anda menghitung variabel B tetapi kemudian menggunakan beberapa variabel A yang dibuat sebelumnya.

Jadi kemungkinan alasan untuk variabel yang tidak digunakan adalah bahwa ada kesalahan dalam kode Anda. Itu sebabnya kompiler memperingatkan Anda. Jika Anda "tidak melakukan" variabel yang tidak digunakan, itu bahkan merupakan hadiah mati.

Ketika Anda melihat peringatan seperti itu, Anda harus memverifikasi kode Anda dan memperbaikinya atau menghapus variabel yang menyinggung. Jika Anda tidak menghapusnya, Anda akan berhenti memperhatikan peringatan ini, dan Anda sebaiknya menonaktifkannya sama sekali. Tetapi pada akhirnya Anda akan kehilangan suatu sore men-debug kode karena satu kesalahan konyol.

Florian F
sumber