Operator kenaikan / penurunan pra / pasca ( ++
dan --
) adalah sintaksis bahasa pemrograman yang cukup standar (setidaknya untuk bahasa prosedural dan berorientasi objek).
Mengapa Ruby tidak mendukung mereka? Saya mengerti Anda dapat mencapai hal yang sama dengan +=
dan -=
, tetapi anehnya rasanya untuk mengecualikan sesuatu seperti itu, terutama karena itu begitu ringkas dan konvensional.
Contoh:
i = 0 #=> 0
i += 1 #=> 1
i #=> 1
i++ #=> expect 2, but as far as I can tell,
#=> irb ignores the second + and waits for a second number to add to i
Saya mengerti Fixnum
tidak dapat diubah, tetapi jika +=
hanya bisa membuat yang baru Fixnum
dan mengaturnya, mengapa tidak melakukan hal yang sama ++
?
Apakah konsistensi dalam tugas yang mengandung =
karakter satu-satunya alasan untuk ini, atau apakah saya kehilangan sesuatu?
ruby
operators
language-design
Andy_Vulhop
sumber
sumber
+=
operator. Dalam CI coba gunakan++
/--
hanya di dalam kondisional, lebih suka untuk yang lebih literal+=
/-=
dalam pernyataan dasar. Mungkin karena saya belajar Python (lama setelah C ...)Jawaban:
Inilah cara Matz (Yukihiro Matsumoto) menjelaskannya di utas lama :
sumber
+=
/-=
ok? Dan tidak1+=1
akan seburuk itu? (Gagal di IRB dengansyntax error, unexpected ASSIGNMENT
)+=
mengganti objek referensi variabel dengan objek yang sama sekali baru. Anda dapat memeriksa ini dengan meneleponi.object_id
sebelum dan sesudahi+=1
. Mengapa itu secara teknis lebih sulit dilakukan++
?++
metode).Salah satu alasannya adalah bahwa hingga sekarang setiap operator penugasan (yaitu operator yang mengubah variabel) ada
=
di dalamnya. Jika Anda menambahkan++
dan--
, itu tidak lagi terjadi.Alasan lainnya adalah karena perilaku
++
dan--
kerap membingungkan orang. Contoh kasus: Nilai pengembaliani++
dalam contoh Anda sebenarnya adalah 1, bukan 2 (nilai baru yaitui
2, namun).sumber
=
di dalamnya" tampaknya masuk akal. Saya bisa menghargai itu sebagai kepatuhan yang kuat terhadap konsistensi.a.capitalize!
tidak menetapkan ulanga
, itu akan mengubah string yanga
merujuk. Referensi lain ke string yang sama akan terpengaruh dan jika Anda melakukannyaa.object_id
sebelum dan sesudah panggilan kecapitalize
, Anda akan mendapatkan hasil yang sama (tidak ada yang benar jika Anda melakukannyaa = a.capitalize
).a.capitalize!
akan mempengaruhi referensi lain ke string yang sama. Itu perbedaan yang sangat praktis. Sebagai contoh jika Anda memilikidef yell_at(name) name.capitalize!; puts "HEY, #{name}!" end
dan kemudian memanggilnya seperti ini:,my_name = "luis"; yell_at(my_name)
nilaimy_name
sekarang akan menjadi"LUIS"
, sedangkan itu tidak akan terpengaruh jika Anda telah menggunakancapitalize
dan tugas.Ini tidak konvensional dalam bahasa OO. Bahkan, tidak ada
++
dalam Smalltalk, bahasa yang menciptakan istilah "pemrograman berorientasi objek" (dan bahasa Ruby paling kuat dipengaruhi oleh). Apa yang Anda maksud adalah bahwa itu konvensional dalam bahasa C dan meniru C. Ruby memang memiliki sintaksis mirip-C, tetapi itu tidak sopan dalam mengikuti tradisi C.Adapun mengapa itu tidak ada di Ruby: Matz tidak menginginkannya. Itu benar-benar alasan utama.
Alasan tidak ada hal seperti itu ada di Smalltalk adalah karena bagian itu dari bahasa override filosofi yang menugaskan variabel secara fundamental berbeda jenis hal daripada mengirim pesan ke objek - itu pada tingkat yang berbeda. Pemikiran ini mungkin memengaruhi Matz dalam mendesain Ruby.
Tidaklah mustahil untuk memasukkannya ke dalam Ruby - Anda dapat dengan mudah menulis preprocessor yang mengubah semuanya
++
menjadi+=1
. tetapi jelas Matz tidak menyukai gagasan tentang operator yang melakukan "tugas tersembunyi." Tampaknya juga agak aneh memiliki operator dengan operan integer tersembunyi di dalamnya. Tidak ada operator lain dalam bahasa yang berfungsi seperti itu.sumber
Saya pikir ada alasan lain:
++
di Ruby tidak akan jauh berguna seperti di C dan penggantinya langsung.Alasannya,
for
kata kunci: sementara itu penting dalam C, sebagian besar berlebihan di Ruby. Sebagian besar iterasi di Ruby dilakukan melalui metode Enumerable, sepertieach
danmap
ketika iterasi melalui beberapa struktur data, danFixnum#times
metode, ketika Anda perlu mengulang beberapa kali.Sebenarnya, sejauh yang saya lihat, sebagian besar waktu
+=1
digunakan oleh orang yang baru saja pindah ke Ruby dari bahasa C-style.Singkatnya, itu benar-benar dipertanyakan apakah metode
++
dan--
akan digunakan sama sekali.sumber
Saya pikir alasan Matz untuk tidak menyukai mereka adalah bahwa itu sebenarnya menggantikan variabel dengan yang baru.
ex:
Sekarang, jika seseorang dapat meyakinkannya bahwa itu harus memanggil #succ! atau apa yang tidak, itu akan lebih masuk akal, dan menghindari masalah. Anda dapat menyarankannya pada inti ruby.
sumber
Anda dapat menentukan
.+
operator peningkatan-diri:Informasi lebih lanjut tentang "class Variable" tersedia di " Class Variable to increment object Fixnum ".
sumber
Dan dalam kata-kata David Black dari bukunya "The Well-Grounded Rubyist":
sumber
Tidak bisakah ini dicapai dengan menambahkan metode baru ke kelas fixnum atau Integer?
mengembalikan 2
Metode "Merusak" tampaknya ditambahkan
!
untuk memperingatkan kemungkinan pengguna, jadi menambahkan metode baru yang disebutnext!
akan cukup banyak melakukan apa yang diminta yaitu.mengembalikan 2 (karena mati rasa telah bertambah)
Tentu saja,
next!
metode harus memeriksa bahwa objek adalah variabel integer dan bukan bilangan real, tetapi ini harus tersedia.sumber
Integer#next
sudah ada (kurang lebih), kecuali disebutInteger#succ
sebaliknya (untuk 'penerus'). TetapiInteger#next!
(atauInteger#succ!
) akan menjadi omong kosong: ingat bahwa metode bekerja pada objek , bukan variabel , jadinumb.next!
akan persis sama dengan1.next!
, yang bisa dikatakan, itu akan bermutasi 1 menjadi sama dengan 2 .++
akan sedikit lebih baik karena bisa menjadi gula sintaksis untuk tugas, tetapi secara pribadi saya lebih suka sintaksis saat ini di mana semua tugas dilakukan dengan=
.Integer#pred
untuk mengambil pendahulunya.Periksa operator ini dari C-family di irb Ruby dan ujilah sendiri:
sumber
(x++)
pernyataan yang tidak valid di Ruby.