วิธีตรวจสอบว่าวัตถุ Ruby เป็นบูลีนหรือไม่


122

ฉันไม่สามารถตรวจสอบได้ว่าวัตถุนั้นเป็นบูลีนได้อย่างง่ายดายหรือไม่ ในรูบี้มีอะไรแบบนี้ไหม?

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

ตอนนี้ฉันกำลังทำสิ่งนี้และต้องการย่อให้สั้นลง:

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

คำตอบ:


136

วิธีที่ง่ายที่สุดที่ฉันคิดได้:

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

6
คลาส X; ท้า!; จุดจบด้วยตนเอง x = X ใหม่; !! x == x # => true
Alexey

5
ใช่เรียกว่าการพิมพ์แบบเป็ดและเป็นหลักการสำคัญของ OOP ผมคิดว่ามันเป็นคุณสมบัติ
Konstantin Haase

62
สั้นไม่ได้แปลว่าง่ายเสมอไป โดยที่ฉันหมายถึง wtf คือ?
Grant Birchmeier

11
เปลี่ยน foo เป็นบูลีนตรวจสอบว่าเหมือนกับ foo หรือไม่
Konstantin Haase

9
โปรดทราบว่าการปฏิเสธสองครั้งถือเป็นรูปแบบที่ไม่ดีสำหรับหมากฮอสบางตัว (เช่นRuboCop )
sschuberth

104

ฉันพบว่าสิ่งนี้กระชับและเป็นเอกสารในตัวเอง:

[true, false].include? foo

หากใช้ Rails หรือ ActiveSupport คุณสามารถสอบถามโดยตรงโดยใช้ไฟล์ in?

foo.in? [true, false]

การตรวจสอบค่าที่เป็นไปได้ทั้งหมดไม่ใช่สิ่งที่ฉันแนะนำสำหรับการลอย แต่เป็นไปได้เมื่อมีค่าที่เป็นไปได้เพียงสองค่าเท่านั้น!


1
คำตอบที่ดีที่สุดแม้ว่าฉันจะชอบfoo == true or foo == falseที่มีคนแสดงความคิดเห็นก็ตาม
Ryan Taylor

3
ฉันชอบสิ่งนี้เพราะมีเจตนาที่คลุมเครือน้อยกว่าไฟล์!!foo == foo.
stringsn88keys

พี ธ อนิกจริงจัง! คำตอบที่มีความหมายมากที่สุดที่นี่
JM Janzen

85

ไม่มีBooleanคลาสใน Ruby วิธีเดียวที่จะตรวจสอบคือทำในสิ่งที่คุณกำลังทำอยู่ (เปรียบเทียบวัตถุกับtrueและfalseหรือคลาสของวัตถุกับTrueClassและFalseClass) คิดไม่ออกว่าทำไมคุณถึงต้องใช้ฟังก์ชันนี้อธิบายได้ไหม? :)

อย่างไรก็ตามหากคุณต้องการฟังก์ชันนี้จริงๆคุณสามารถแฮ็คได้ใน:

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

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

1
พยายามทำการพิมพ์ตามค่าปัจจุบัน
Lance Pollard

75
'ทำไมคุณถึงทำแบบนั้น?' (และอนุพันธ์) เป็นเพียงหนึ่งในคำถามที่น่ารำคาญที่สุดที่วิศวกรสามารถสร้างได้ :)
vemv

11
+1 เพราะฉันสามารถใช้สิ่งนี้ใน rspec เช่น:expect(some_method?(data)).to be_a(Boolean)
Automatico

3
กรณีอื่น ๆ ที่จำเป็นต้องตรวจสอบประเภทคือเมื่อคุณใช้อะแด็ปเตอร์ฐานข้อมูลและต้องการห่อสตริงด้วย"quotes"ตัวเลขและบูลีน แต่ไม่ใช่
Daniel Garmoshka

23

ตามที่ระบุไว้ข้างต้นไม่มีคลาสบูลีนเพียง TrueClass และ FalseClass อย่างไรก็ตามคุณสามารถใช้วัตถุใด ๆ เป็นหัวข้อของ if / เว้นแต่และทุกอย่างเป็นจริงยกเว้นอินสแตนซ์ของ FalseClass และศูนย์

การทดสอบบูลีนส่งคืนอินสแตนซ์ของ FalseClass หรือ TrueClass

(1 > 0).class #TrueClass

Monkeypatch to Object ต่อไปนี้จะบอกคุณว่าบางสิ่งเป็นอินสแตนซ์ของ TrueClass หรือ FalseClass

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

การรันการทดสอบบางอย่างกับ irb ให้ผลลัพธ์ดังต่อไปนี้

?> "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
self == true or self == falseเพียงง่ายในการเขียน นี่เป็นอินสแตนซ์เดียวของ TrueClass และ FalseClass
ชัค

@chuck ที่ส่งกลับผลลัพธ์เดียวกันยกเว้น Time.now.boolean? ซึ่งคืนค่าศูนย์ มีความคิดว่าทำไม?
Steve Weet

การกำหนดคลาสตรวจสอบตนเองในวิธีการนั้นค่อนข้างไม่โอ้อวด คุณควรกำหนดสองเวอร์ชันbooleanหนึ่งสำหรับ TrueClass / FalseClass และอีกเวอร์ชันสำหรับ Object
Konstantin Haase

4
เหตุผลก็คือข้อบกพร่องในเวอร์ชันของTime#==Ruby 1.8 ทำให้การเปรียบเทียบกับค่าที่ไม่ใช่เวลาส่งคืนค่าศูนย์แทนที่จะเป็นเท็จ
Chuck

17

หากโค้ดของคุณสามารถเขียนเป็นคำสั่งกรณีได้อย่างสมเหตุสมผลสิ่งนี้ก็ค่อนข้างดี:

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

6

วัตถุที่เป็นบูลีนจะมีคลาส TrueClass หรือ FalseClass ดังนั้นซับเดียวต่อไปนี้ควรทำเคล็ดลับ

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

ต่อไปนี้จะให้ผลการตรวจสอบประเภทบูลีนจริง / เท็จ

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

4

ลองใช้(x == true) ^ (x == false)หมายเหตุนี้ คุณต้องมีวงเล็บ แต่สวยงามและกะทัดรัดกว่า

แม้จะผ่านคำแนะนำเช่น "cuak" แต่ไม่ใช่ "cuak" ... class X; def !; self end end ; x = X.new; (x == true) ^ (x == false)

หมายเหตุ : ดูว่านี่เป็นพื้นฐานที่คุณสามารถใช้เป็นภาษาอื่นได้เช่นกันซึ่งไม่ได้ระบุว่า "thing is boolean"

หมายเหตุ 2 : นอกจากนี้คุณยังสามารถใช้สิ่งนี้เพื่อบอกว่าเป็นหนึ่งใน ??:"red", "green", "blue"ถ้าคุณadd more XORS... หรือพูดว่าสิ่งนี้เป็นหนึ่งใน ??:4, 5, 8, 35.


ทำไมต้อง XOR ทำไมไม่หรือ?
Nakilon

2

อัญมณีนี้เพิ่มคลาสบูลีนให้กับ Ruby ด้วยวิธีการที่มีประโยชน์

https://github.com/RISCfuture/boolean

ใช้:

require 'boolean'

แล้วของคุณ

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

จะทำงานได้ตามที่คุณคาดหวัง


0

ไม่เหมือนคุณมีรหัสของคุณ ไม่มีคลาสใด ๆ ที่ชื่อบูลีน ตอนนี้ด้วยคำตอบทั้งหมดที่คุณมีคุณควรจะสร้างและใช้งานได้ คุณรู้วิธีสร้างชั้นเรียนไม่ใช่เหรอ? ฉันมาที่นี่เพราะฉันแค่สงสัยความคิดนี้เอง หลายคนอาจจะบอกว่า "ทำไมคุณต้องรู้ว่า Ruby ใช้ Boolean อย่างไร" นั่นคือเหตุผลที่คุณได้รับคำตอบที่คุณทำ ขอบคุณสำหรับคำถาม อาหารสมอง. ทำไม Ruby ถึงไม่มีคลาสบูลีน?

NameError: uninitialized constant Boolean

โปรดทราบว่า Objects ไม่มีประเภท พวกเขาเป็นชั้นเรียน ออบเจ็กต์มีข้อมูล นั่นเป็นเหตุผลว่าทำไมเมื่อคุณบอกว่าประเภทข้อมูลมันเป็นการเรียกชื่อผิดเล็กน้อย

ลองแรนด์ 2 ด้วยเพราะแรนด์ 1 ดูเหมือนจะให้ 0 เสมอแรนด์ 2 จะให้ 1 หรือ 0 คลิกรันสองสามครั้งที่นี่ https://repl.it/IOPx/7

แม้ว่าฉันจะไม่รู้วิธีการสร้างคลาสบูลีนด้วยตัวเอง ฉันเคยทดลองมาแล้ว แต่ ...

class Boolean < TrueClass
  self
end

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

อย่างน้อยเราก็มีคลาสนั้นแล้ว แต่ใครจะรู้ว่าจะได้ค่าที่ถูกต้อง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.