Hanya ingin tahu apa yang !!ada di Ruby.
Jawaban:
Tidak tidak. Ini digunakan untuk mengonversi nilai menjadi boolean:
!!nil #=> false
!!"abc" #=> true
!!false #=> false
Ini biasanya tidak perlu digunakan karena satu-satunya nilai palsu untuk Ruby adalah nildan false, jadi biasanya yang terbaik adalah membiarkan konvensi itu berlaku.
Anggap saja sebagai
!(!some_val)
Satu hal yang digunakannya secara sah adalah mencegah sebagian besar data dikembalikan. Misalnya Anda mungkin tidak ingin mengembalikan 3MB data gambar dalam has_image?metode Anda , atau Anda mungkin tidak ingin mengembalikan seluruh objek pengguna Anda dalam logged_in?metode ini. Menggunakan !!mengubah objek-objek ini menjadi true/ false.
.nil?daripada menggunakan !!? Apakah ada bedanya?
!!true #=> truedantrue.nil? #=> false
!berarti negate boolean state, two !s is nothing special, selain double negation.
!true == false
# => true
Ini biasanya digunakan untuk memaksa metode mengembalikan boolean. Ini akan mendeteksi segala jenis kebenaran, seperti string, integer dan apa yang tidak, dan mengubahnya menjadi boolean.
!"wtf"
# => false
!!"wtf"
# => true
Kasus penggunaan yang lebih nyata:
def title
"I return a string."
end
def title_exists?
!!title
end
Ini berguna ketika Anda ingin memastikan bahwa boolean dikembalikan. IMHO itu agak sia-sia, meskipun, melihat bahwa keduanya if 'some string'dan if truemerupakan aliran yang sama persis, tetapi beberapa orang merasa berguna untuk mengembalikan boolean secara eksplisit.
title, sebaiknya lakukan hal yang paling mendekati ... Saya kira
Perhatikan bahwa idiom ini juga ada di bahasa pemrograman lain. C tidak memiliki booltipe intrinsik , jadi semua boolean diketik sebagai intgantinya, dengan nilai kanonik 0atau 1. Ambil contoh ini (tanda kurung ditambahkan untuk kejelasan):
!(1234) == 0
!(0) == 1
!(!(1234)) == 1
Sintaks "not-not" mengonversi bilangan bulat bukan nol menjadi 1, nilai sebenarnya boolean kanonis.
Secara umum, saya merasa jauh lebih baik untuk membuat perbandingan yang masuk akal daripada menggunakan ungkapan yang tidak umum ini:
int x = 1234;
if (!!x); // wtf mate
if (x != 0); // obvious
Ini berguna jika Anda perlu melakukan eksklusif atau . Menyalin dari jawaban Matt Van Horn dengan sedikit modifikasi:
1 ^ true
TypeError: can't convert true into Integer
!!1 ^ !!true
=> false
Saya menggunakannya untuk memastikan dua variabel keduanya nihil, atau keduanya bukan nihil.
raise "Inconsistency" if !!a ^ !!b
Ini adalah "negatif ganda", tetapi praktiknya tidak disarankan. Jika Anda menggunakan rubocop , Anda akan melihatnya mengeluh pada kode tersebut dengan aStyle/DoubleNegation pelanggaran.
The pemikiran negara:
Karena ini samar dan biasanya berlebihan, ini harus dihindari [lalu parafrase:] Ubah
!!somethingke!something.nil?
!!false # => falsesementara!false.nil? # => true
!(foo.nil? || foo == false)- lebih bertele-tele, ya, tetapi tidak terlalu samar.
Memahami cara kerjanya dapat berguna jika Anda perlu mengubah, katakanlah, enumerasi menjadi boolean. Saya memiliki kode yang melakukan hal itu, menggunakan classy_enumpermata:
class LinkStatus < ClassyEnum::Base
def !
return true
end
end
class LinkStatus::No < LinkStatus
end
class LinkStatus::Claimed < LinkStatus
def !
return false
end
end
class LinkStatus::Confirmed < LinkStatus
def !
return false
end
end
class LinkStatus::Denied < LinkStatus
end
Kemudian di kode layanan yang saya miliki, misalnya:
raise Application::Error unless !!object.link_status # => raises exception for "No" and "Denied" states.
Secara efektif operator bangbang telah menjadi apa yang mungkin saya tulis sebagai metode yang disebut to_bool.
Jawaban lain telah membahas apa !! dilakukan dan apakah itu praktik yang baik atau tidak.
Namun, tidak ada jawaban yang memberikan "cara Ruby standar" untuk mengubah nilai menjadi boolean.
true & variable
TrueClass, kelas dari nilai Ruby true, mengimplementasikan metode &, yang didokumentasikan sebagai berikut:
Pengembalian
falsejikaobjininilataufalse,truesebaliknya.
Mengapa menggunakan negasi ganda yang kotor ketika perpustakaan standar telah Anda liput?