Saya menggunakan kode ini untuk membiarkan pengguna memasukkan nama sementara program menyimpannya dalam array sampai mereka memasukkan string kosong (mereka harus menekan enter setelah setiap nama):
people = []
info = 'a' # must fill variable with something, otherwise loop won't execute
while not info.empty?
info = gets.chomp
people += [Person.new(info)] if not info.empty?
end
Kode ini akan terlihat jauh lebih bagus di do ... while:
people = []
do
info = gets.chomp
people += [Person.new(info)] if not info.empty?
while not info.empty?
Dalam kode ini saya tidak perlu menetapkan info ke beberapa string acak.
Sayangnya jenis loop ini tampaknya tidak ada di Ruby. Adakah yang bisa menyarankan cara yang lebih baik untuk melakukan ini?
loop do; ...; break if ...; end
,?Jawaban:
PERHATIAN :
Itu
begin <code> end while <condition>
ditolak oleh penulis Ruby Matz. Sebaliknya ia menyarankan menggunakanKernel#loop
, misalnyaInilah pertukaran email pada 23 November 2005 di mana Matz menyatakan:
RosettaCode wiki memiliki kisah serupa:
sumber
begin end while
metode tampaknya tidak benar. Terima kasih telah memberi saya makanan ternak yang saya butuhkan untuk meyakinkan anggota tim lainnya.Awalnya ditulis oleh Jeremy Voorhis . Konten telah disalin di sini karena tampaknya telah diambil dari situs asal. Salinan juga dapat ditemukan di Web Archive dan di Ruby Buzz Forum . -Bill si Kadal
sumber
begin .. end
agak tidak disukai. Gunakanloop do .. break if <condition>
sebagai gantinya.Seperti ini:
Referensi: Ruby Tersembunyi do {} while () Loop
sumber
until info.empty?
daripadawhile not info.empty?
.Bagaimana dengan ini?
sumber
Ini artikel teks lengkap dari tautan mati hubbardr ke blog saya.
Saya menemukan cuplikan berikut saat membaca sumber untuk
Tempfile#initialize
di pustaka inti Ruby:Pada pandangan pertama, saya berasumsi
while
pengubah akan dievaluasi sebelum isinyabegin...end
, tapi itu tidak terjadi. Mengamati:Seperti yang Anda harapkan, loop akan terus dieksekusi ketika pengubah benar.
Sementara saya akan senang tidak pernah melihat idiom ini lagi,
begin...end
cukup kuat. Berikut ini adalah idiom umum untuk memoize metode one-liner tanpa params:Berikut ini adalah cara yang jelek, tetapi cepat untuk menghafal sesuatu yang lebih rumit:
sumber
Ini berfungsi dengan benar sekarang:
Tapi, itu mungkin dihapus di masa depan, karena
begin
pernyataan itu berlawanan dengan intuisi. Lihat: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/6745Matz (Pencipta Ruby) merekomendasikan melakukannya dengan cara ini:
sumber
Dari apa yang saya kumpulkan, Matz tidak suka konstruk itu
karena, itu semantik berbeda dari
karena konstruk pertama mengeksekusi kode terlebih dahulu sebelum memeriksa kondisi, dan konstruk kedua menguji kondisi terlebih dahulu sebelum mengeksekusi kode (jika pernah). Saya menganggapnya Matz lebih memilih untuk mempertahankan konstruk kedua karena cocok dengan konstruksi satu baris pernyataan if.
Saya tidak pernah menyukai konstruk kedua bahkan untuk pernyataan if. Dalam semua kasus lain, komputer menjalankan kode kiri-ke-kanan (mis. || dan &&) dari atas ke bawah. Manusia membaca kode dari kiri ke kanan dari atas ke bawah.
Saya menyarankan konstruksi berikut sebagai gantinya:
Saya tidak tahu apakah saran-saran itu akan diuraikan dengan seluruh bahasa. Tetapi bagaimanapun saya lebih suka menjaga eksekusi dari kiri ke kanan serta konsistensi bahasa.
sumber
sumber
while true
bisa diganti denganloop do
.while true
bisa diganti denganloop do
. Tapi saya menguji kedua konstruksi dengan banyak iterasi di dalam loop, dan menemukan bahwawhile true
setidaknya 2x lebih cepat daripadaloop do
. Tidak dapat menjelaskan perbedaannya, tetapi pasti ada di sana. (Ditemukan saat menguji Advent of Code 2017, hari 15.)Ini satu lagi:
sumber
unless
tepat di depan dan saya tidak membaca banyak kode (yang bisa lebih dari yang ditunjukkan di sini) hanya untuk menemukan 'menggantung'unless
di akhir. Ini adalah prinsip umum dalam kode bahwa pengubah dan kondisi lebih mudah digunakan ketika mereka 'di depan' seperti ini.sumber