Cara memeriksa apakah objek Ruby adalah Boolean


122

Saya tidak bisa memeriksa apakah suatu objek adalah boolean dengan mudah. Apakah ada yang seperti ini di Ruby?

true.is_a?(Boolean)
false.is_a?(Boolean)

Sekarang saya sedang melakukan ini dan ingin mempersingkatnya:

some_var = rand(1) == 1 ? true : false
(some_var.is_a?(TrueClass) || some_var.is_a?(FalseClass))

Jawaban:


136

Cara paling sederhana yang dapat saya pikirkan:

# checking whether foo is a boolean
!!foo == foo

6
kelas X; def!; ujung diri sendiri; x = X. baru; !! x == x # => benar
Alexey

5
Ya, itulah yang disebut bebek mengetik dan prinsip inti OOP. Saya pikir itu sebuah fitur.
Konstantin Haase

62
Pendek tidak selalu berarti sederhana. Maksud saya, apa itu?
Grant Birchmeier

11
Mengubah foo menjadi boolean, periksa apakah itu sama dengan foo.
Konstantin Haase

9
Perhatikan bahwa negasi ganda dianggap gaya buruk oleh beberapa checker (seperti RuboCop ).
sschuberth

104

Saya merasa ini ringkas dan mendokumentasikan diri sendiri:

[true, false].include? foo

Jika menggunakan Rails atau ActiveSupport, Anda bahkan dapat melakukan kueri langsung menggunakan in?

foo.in? [true, false]

Memeriksa semua nilai yang mungkin bukanlah sesuatu yang saya rekomendasikan untuk float, tetapi layak jika hanya ada dua nilai yang memungkinkan!


1
jawaban terbaik sejauh ini, meskipun saya juga menyukai foo == true or foo == falseseseorang yang memberikan komentar.
Ryan Taylor

3
Saya suka ini karena maksudnya kurang samar daripada !!foo == foo.
stringsn88keys

Benar-benar pythonic! Jelas merupakan jawaban paling semantik di sini sejauh ini.
JM Janzen

85

Tidak ada Booleankelas di Ruby, satu-satunya cara untuk memeriksanya adalah dengan melakukan apa yang Anda lakukan (membandingkan objek dengan truedan falseatau kelas objek terhadap TrueClassdanFalseClass ). Tidak dapat memikirkan mengapa Anda membutuhkan fungsi ini, dapatkah Anda menjelaskan? :)

Namun, jika Anda benar - benar membutuhkan fungsi ini, Anda dapat meretasnya di:

module Boolean; end
class TrueClass; include Boolean; end
class FalseClass; include Boolean; end

true.is_a?(Boolean) #=> true
false.is_a?(Boolean) #=> true

1
mencoba melakukan typecasting berdasarkan nilai saat ini.
Lance Pollard

75
'Kenapa kamu pernah apa itu?' (dan turunannya) hanyalah salah satu pertanyaan paling menjengkelkan yang dapat diajukan oleh seorang insinyur :)
vemv

11
+1 karena saya dapat menggunakan ini di rspec seperti:expect(some_method?(data)).to be_a(Boolean)
Automatico

3
Kasus lain ketika perlu memeriksa jenis, adalah ketika Anda menerapkan adaptor database dan perlu membungkus string dengan "quotes"tetapi bukan angka dan boolean
Daniel Garmoshka

23

Seperti yang dinyatakan di atas tidak ada kelas boolean hanya TrueClass dan FalseClass namun Anda dapat menggunakan objek apa pun sebagai subjek jika / kecuali dan semuanya benar kecuali instance FalseClass dan nil

Pengujian Boolean mengembalikan instance FalseClass atau TrueClass

(1 > 0).class #TrueClass

Monkeypatch to Object berikut akan memberi tahu Anda apakah sesuatu adalah instance TrueClass atau FalseClass

class Object
  def boolean?
    self.is_a?(TrueClass) || self.is_a?(FalseClass) 
  end
end

Menjalankan beberapa tes dengan irb memberikan hasil sebagai berikut

?> "String".boolean?
=> false
>> 1.boolean?
=> false
>> Time.now.boolean?
=> false
>> nil.boolean?
=> false
>> true.boolean?
=> true
>> false.boolean?
=> true
>> (1 ==1).boolean?
=> true
>> (1 ==2).boolean?
=> true

4
Lebih sederhana hanya untuk menulis self == true or self == false. Itu adalah satu-satunya contoh TrueClass dan FalseClass.
Chuck

@chuck yang mengembalikan hasil yang sama kecuali untuk Time.now.boolean? yang mengembalikan nihil. Tahu kenapa?
Steve Weet

Mendefinisikan pemeriksaan kelas pada diri sendiri dalam metode ini agak tidak tepat. Anda harus menentukan dua versi boolean, satu untuk TrueClass / FalseClass dan satu lagi untuk Object.
Konstantin Haase

4
Alasannya adalah bahwa bug di versi Time#==Ruby 1.8 menyebabkan perbandingan nilai non-Time menghasilkan nil, bukan false.
Chuck

17

Jika kode Anda dapat dengan bijaksana ditulis sebagai pernyataan kasus, ini cukup baik:

case mybool
when TrueClass, FalseClass
  puts "It's a bool!"
else
  puts "It's something else!"
end

6

Objek yang berupa boolean akan memiliki kelas TrueClass atau FalseClass sehingga satu baris berikut harus melakukan triknya

mybool = true
mybool.class == TrueClass || mybool.class == FalseClass
=> true

Berikut ini juga akan memberi Anda hasil pemeriksaan tipe boolean benar / salah

mybool = true    
[TrueClass, FalseClass].include?(mybool.class)
=> true

4

Jadi cobalah (x == true) ^ (x == false)catatan ini, Anda memerlukan tanda kurung tetapi ini lebih indah dan ringkas.

Itu bahkan melewati saran seperti "cuak" tetapi bukan "cuak" ... class X; def !; self end end ; x = X.new; (x == true) ^ (x == false)

Catatan : Perhatikan bahwa ini sangat mendasar sehingga Anda dapat menggunakannya dalam bahasa lain juga, yang tidak memberikan "thing is boolean".

Catatan 2 : Anda juga dapat menggunakan ini untuk mengatakan sesuatu adalah salah satu dari ??:"red", "green", "blue"jika Andaadd more XORS... atau mengatakan hal ini adalah salah satu dari ??:4, 5, 8, 35.


Mengapa XOR? Mengapa tidak ATAU?
Nakilon


0

Tidak. Tidak seperti Anda memiliki kode Anda. Tidak ada kelas yang bernama Boolean. Sekarang dengan semua jawaban yang Anda miliki, Anda harus dapat membuat dan menggunakannya. Anda tahu cara membuat kelas bukan? Saya datang ke sini hanya karena saya sendiri yang bertanya-tanya tentang ide ini. Banyak orang mungkin berkata "Kenapa? Kamu harus tahu bagaimana Ruby menggunakan Boolean". Itulah mengapa Anda mendapatkan jawaban yang Anda lakukan. Jadi terima kasih atas pertanyaannya. Bahan untuk dipikirkan. Mengapa Ruby tidak memiliki kelas Boolean?

NameError: uninitialized constant Boolean

Perlu diingat bahwa Objek tidak memiliki tipe. Mereka adalah kelas. Objek memiliki data. Jadi itulah mengapa ketika Anda mengatakan tipe data itu sedikit keliru.

Coba juga rand 2 karena rand 1 sepertinya selalu memberikan 0. rand 2 akan memberikan 1 atau 0 klik berjalan beberapa kali di sini. https://repl.it/IOPx/7

Meskipun saya tidak tahu bagaimana cara membuat kelas Boolean sendiri. Saya telah bereksperimen dengan itu tapi ...

class Boolean < TrueClass
  self
end

true.is_a?(Boolean) # => false
false.is_a?(Boolean) # => false

Setidaknya kita memiliki kelas itu sekarang tetapi siapa yang tahu bagaimana mendapatkan nilai yang benar?

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.