ทับทิมมีความคิดที่เป็นสากลของ " truthiness " และ " falsiness "
ทับทิมไม่ได้มีสองชั้นที่เฉพาะเจาะจงสำหรับวัตถุบูลีนTrueClass
และFalseClass
มีอินสแตนซ์เดี่ยวแสดงโดยตัวแปรพิเศษtrue
และfalse
ตามลำดับ
อย่างไรก็ตามtruthinessและfalsinessไม่ จำกัด เฉพาะกรณีของทั้งสองเรียนที่เป็นแนวคิดที่เป็นสากลและนำไปใช้กับทุกวัตถุเดียวในรูบี วัตถุทุกคนเป็นอย่างใดอย่างหนึ่งtruthyหรือfalsy กฎนั้นง่ายมาก โดยเฉพาะวัตถุสองอย่างเท่านั้นที่เป็นเท็จ :
nil
อินสแตนซ์ของNilClass
และfalse
อินสแตนซ์เดี่ยวของFalseClass
ทุกวัตถุอื่น ๆ เดียวคือtruthy ซึ่งรวมถึงวัตถุที่ถือว่าเป็นเท็จในภาษาการเขียนโปรแกรมอื่นเช่น
กฎเหล่านี้สร้างขึ้นในภาษาและไม่สามารถระบุได้โดยผู้ใช้ ไม่มีto_bool
การแปลงโดยนัยหรืออะไรที่คล้ายกัน
นี่คือใบเสนอราคาจากข้อกำหนดภาษา ISO Ruby :
6.6 ค่าบูลีน
วัตถุถูกแบ่งออกเป็นทั้งวัตถุ trueishหรือวัตถุ falseish
เท็จเท่านั้นและไม่มีวัตถุปลอม falseเป็นอินสแตนซ์เดียวของคลาส
FalseClass
(ดู 15.2.6) ซึ่งfalse-expressionประเมินค่า (ดู 11.5.4.8.3) nilเป็นเพียงตัวอย่างของคลาสNilClass
(ดู 15.2.4) ซึ่งnil-expression จะประเมิน (ดู 11.5.4.8.2)วัตถุอื่นที่ไม่ใช่falseและไม่มีการจัดประเภทเป็นวัตถุที่แท้จริง trueเป็นเพียงอินสแตนซ์เดียวของคลาส
TrueClass
(ดู 15.2.5) ซึ่งTrue-expression จะประเมิน (ดู 11.5.4.8.3)
Ruby / Spec ที่รันได้ดูเหมือนจะยอมรับ :
it "considers a non-nil and non-boolean object in expression result as true" do if mock('x') 123 else 456 end.should == 123 end
จากแหล่งข้อมูลทั้งสองนี้ฉันจะสมมติว่าRegexp
s นั้นเป็นความจริงแต่จากการทดสอบของฉันพวกเขาไม่ได้:
if // then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are falsy'
ผมทดสอบนี้ในYARV 2.7.0-preview1 , TruffleRuby 19.2.0.1และJRuby 9.2.8.0 การใช้งานทั้งสามเห็นด้วยกันและไม่เห็นด้วยกับข้อกำหนดภาษา ISO Ruby และการตีความ Ruby / Spec ของฉัน
อีกอย่างแม่นยำRegexp
วัตถุที่เป็นผลมาจากการประเมินRegexp
ตัวอักษรเป็นfalsyในขณะที่Regexp
วัตถุที่เป็นผลมาจากการแสดงออกบางส่วนอื่น ๆ ที่มีtruthy :
r = //
if r then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are truthy'
นี่เป็นข้อบกพร่องหรือพฤติกรรมที่ต้องการหรือไม่?
!!//
เป็นเท็จ แต่!!/r/
เป็นความจริง แปลกแน่นอน
!!/r/
ผลิตขึ้นfalse
สำหรับฉันโดยใช้ (RVM) Ruby 2.4.1
//
ในif // then
ถูกตีความว่าเป็นการทดสอบ (ทางลัดสำหรับif //=~nil then
) (ที่มักจะเป็นสิ่งที่ผิดเพี้ยนไม่ว่ารูปแบบ) และไม่เป็นอินสแตนซ์ Regexp
Regex.new("a")
คือความจริง