Perbedaan antara "dan" dan && di Ruby?

Jawaban:

349

andsama seperti &&tetapi dengan diutamakan lebih rendah . Keduanya menggunakan evaluasi hubung singkat .

PERINGATAN: andbahkan memiliki prioritas lebih rendah daripada =biasanya Anda ingin menghindari and. Contoh kapan andharus digunakan dapat ditemukan dalam Panduan Rails di bawah " Menghindari Kesalahan Render Ganda ".

Dominic Rodger
sumber
50
Ini akan menjadi ide yang baik untuk menentukan bahwa seseorang biasanya harus menggunakan &&, sementara andharus digunakan untuk kasus yang sangat spesifik.
Marc-André Lafortune
10
Penjelasan lain yang bagus di sini: devblog.avdi.org/2010/08/02/using-and-and-and-or-in-ruby .
Andrew Marshall
17
Dari tautan Andrew Marshall: "Cara lain untuk berpikir andadalah sebagai ifpengubah pernyataan terbalik : next if widget = widgets.popmenjadi widget = widgets.pop and next. Itu cara yang bagus untuk meletakkannya, benar-benar membuatnya" klik "di kepalaku (Dan orseperti unlesspengubah terbalik .)
GMA
1
Gabungkan jawaban ini dengan perincian jawaban tadman dan Anda mendapatkan keseluruhan gambarannya.
sargas
5
Avdi memperbarui pendapatnya tentang kapan harus menggunakan dan vs. &&. Pada dasarnya gunakan 'dan' dan 'atau' untuk aliran kontrol karena mereka lebih diutamakan. devblog.avdi.org/2014/08/26/…
EricC
238

Perbedaan praktisnya adalah kekuatan yang mengikat, yang dapat mengarah pada perilaku aneh jika Anda tidak siap untuk itu:

foo = :foo
bar = nil

a = foo and bar
# => nil
a
# => :foo

a = foo && bar
# => nil
a
# => nil

a = (foo and bar)
# => nil
a
# => nil

(a = foo) && bar
# => nil
a
# => :foo

Hal yang sama berlaku untuk ||dan or.

anak laki-laki
sumber
2
a = foo and bar dan (a = foo ) && bar membuktikan bahwa andmemiliki prioritas lebih rendah dari &&.
sargas
saya tidak mengerti: apa yang dimaksud dengan "foo and bar" untuk kembali?
BKSpurgeon
a = foo and barsetara dengan (a = :foo) and nil. Karena penugasan mengembalikan nilai yang benar secara logis ( :foo) maka bagian kedua mengevaluasi, yang gagal, kembali nil.
tadman
61

The Ruby Style Guide mengatakan lebih baik daripada yang saya bisa:

Gunakan && / || untuk ekspresi boolean, dan / atau untuk aliran kontrol. (Aturan praktis: Jika Anda harus menggunakan tanda kurung luar, Anda menggunakan operator yang salah.)

# boolean expression
if some_condition && some_other_condition
  do_something
end

# control flow
document.saved? or document.save!
Andrew Grimm
sumber
53
Sebenarnya panduan ini sekarang mengatakan untuk menghindari and/ orsepenuhnya, dan mereka mungkin ada benarnya. Seringkali penggunaannya dalam aliran kontrol dapat lebih jelas ditulis dengan if/ unlessoperator (misalnya document.save! unless document.saved?)
Yarin
@akostadinov jika Anda tidak trolling: panduan Ruby Style tidak ditulis oleh pembuat Ruby. Ruby dibuat oleh Yukihiro Matsumoto dan yang lainnya, sedangkan Ruby Style Guide terutama oleh Bozhidar Batsov.
Andrew Grimm
2
@AndrewGrimm, terima kasih, senang tahu. Maaf untuk trolling tapi saya benar-benar bingung dengan beberapa aspek realitas ruby. Satu hal yang pasti - setiap proyek ruby ​​membutuhkan kebijakan gaya yang ketat untuk menjaga basis kode tetap terpelihara.
akostadinov
37

||dan &&ikat dengan prioritas yang Anda harapkan dari operator boolean dalam bahasa pemrograman ( &&sangat kuat, ||sedikit kurang kuat).

anddan ormemiliki prioritas lebih rendah.

Misalnya, tidak seperti ||, ormemiliki prioritas lebih rendah daripada =:

> a = false || true
 => true 
> a
 => true 
> a = false or true
 => true 
> a
 => false

Demikian juga, tidak seperti &&, andjuga memiliki prioritas lebih rendah daripada =:

> a = true && false
 => false 
> a
 => false 
> a = true and false
 => false 
> a
 => true 

Terlebih lagi, tidak seperti &&dan ||, anddan orikat dengan prioritas yang sama:

> !puts(1) || !puts(2) && !puts(3)
1
 => true
> !puts(1) or !puts(2) and !puts(3)
1
3
 => true 
> !puts(1) or (!puts(2) and !puts(3))
1
 => true

Ikatan yang lemah anddan ormungkin berguna untuk keperluan kontrol-aliran: lihat http://devblog.avdi.org/2010/08/02/using-and-and-and-and-or-in-ruby/ .

Gabe Kopley
sumber
2
"tidak seperti ||, ormemiliki prioritas lebih rendah dari =" ... sekarang lebih masuk akal, terima kasih!
Steph Sharp
18

andmemiliki prioritas lebih rendah dari &&.

Tetapi untuk pengguna yang sederhana, masalah mungkin terjadi jika digunakan bersama dengan operator lain yang diutamakan di antara, misalnya, operator penugasan:

def happy?() true; end
def know_it?() true; end

todo = happy? && know_it? ? "Clap your hands" : "Do Nothing"

todo
# => "Clap your hands"

todo = happy? and know_it? ? "Clap your hands" : "Do Nothing"

todo
# => true
Santhosh
sumber
1
Terima kasih, tetapi bagaimana presedensi "dan" berbeda dari "&&"?
BKSpurgeon
2
@ BKSpurgeon Lihat di sini untuk daftar prioritas operator di Ruby.
thutt
5

andmemiliki prioritas lebih rendah, sebagian besar kami menggunakannya sebagai pengubah aliran kontrol seperti if:

next if widget = widgets.pop

menjadi

widget = widgets.pop and next

Untuk or:

raise "Not ready!" unless ready_to_rock?

menjadi

ready_to_rock? or raise "Not ready!"

Saya lebih suka menggunakan iftetapi tidak and, karena iflebih dapat dimengerti, jadi saya abaikan saja anddan or.

Lihat " Menggunakan" dan "dan" atau "di Ruby " untuk informasi lebih lanjut.

Feuda
sumber
0

Saya tidak tahu apakah ini maksud Ruby atau apakah ini bug tetapi coba kode ini di bawah ini. Kode ini dijalankan pada Ruby versi 2.5.1 dan pada sistem Linux.

puts 1 > -1 and 257 < 256
# => false

puts 1 > -1 && 257 < 256
# => true
Kevin Ng
sumber
1
@JakubArnold Sarcasm tidak pernah membantu. Contohnya terkadang.
BobRodes
@ BobRodes Itu bukan sarkasme. Ada 7 jawaban, 6 di antaranya sudah memiliki contoh.
Jakub Arnold
1
@ JakubArnold Saya masih menemukan contoh ini bermanfaat.
BobRodes
Saya mendapatkan hasil yang aneh juga. v1 = true dan false p v1 # => app.rb: true, IRB: false v2 = true && false p v2 # => app.rb: false, IRB: false menempatkan 1> -1 && 257 <256 # => app.rb: false, IRB: false
Rich_F