Ruby có một ý tưởng phổ quát của " truthiness " và " falsiness ".
Ruby không có hai lớp học cụ thể cho các đối tượng Boolean, TrueClass
và FalseClass
, với trường hợp singleton biểu hiện bằng các biến đặc biệt true
và false
tương ứng.
Tuy nhiên, truthiness và falsiness không giới hạn trường hợp của hai lớp học, khái niệm này là phổ biến và áp dụng cho mọi đối tượng duy nhất trong Ruby. Mỗi đối tượng là một trong hai truthy hoặc falsy . Các quy tắc rất đơn giản. Cụ thể, chỉ có hai đối tượng là giả mạo :
nil
, ví dụ đơn lẻ củaNilClass
vàfalse
, ví dụ đơnFalseClass
Mỗi đối tượng khác là sự thật . Điều này bao gồm đối tượng thậm chí được coi là falsy bằng các ngôn ngữ lập trình khác, chẳng hạn như
Các quy tắc này được tích hợp vào ngôn ngữ và không thể xác định được. Không có to_bool
chuyển đổi ngầm hoặc bất cứ điều gì tương tự.
Dưới đây là trích dẫn từ Đặc tả ngôn ngữ ISO của Ruby :
6.6 Giá trị Boolean
Một đối tượng được phân loại thành một đối tượng thật hoặc một đối tượng giả .
Chỉ có sai và không là đối tượng giả. false là trường hợp duy nhất của lớp
FalseClass
(xem 15.2.6), theo đó một biểu thức sai đánh giá (xem 11.5.4.8.3). nil là ví dụ duy nhất của lớpNilClass
(xem 15.2.4), theo đó một biểu thức nil đánh giá (xem 11.5.4.8.2).Các đối tượng khác với false và nil được phân loại thành các đối tượng thật. true là ví dụ duy nhất của lớp
TrueClass
(xem 15.2.5), theo đó một biểu thức đúng đánh giá (xem 11.5.4.8.3).
Ruby / Spec thực thi dường như đồng ý :
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
Theo hai nguồn đó, tôi cho rằng đó Regexp
cũng là sự thật , nhưng theo thử nghiệm của tôi, họ không:
if // then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are falsy'
Tôi đã thử nghiệm điều này trên YARV 2.7.0-preview1 , TruffleRuby 19.2.0.1 và JRuby 9.2.8.0 . Tất cả ba triển khai đều đồng ý với nhau và không đồng ý với Đặc tả ngôn ngữ ISO của Ruby và cách giải thích của tôi về Ruby / Spec.
Chính xác hơn, Regexp
đối tượng mà là kết quả của việc đánh giá Regexp
literals là falsy , trong khi Regexp
đối tượng mà là kết quả của một số biểu hiện khác là truthy :
r = //
if r then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are truthy'
Đây có phải là một lỗi, hoặc hành vi mong muốn?
!!//
là sai nhưng !!/r/
là đúng Thực sự kỳ lạ.
!!/r/
sản xuất false
cho tôi bằng cách sử dụng (RVM) Ruby 2.4.1.
//
trong đó if // then
được hiểu là một bài kiểm tra (một lối tắt cho if //=~nil then
) (đó luôn là giả mạo bất kể mẫu nào) và không phải là một ví dụ Regapi.
Regex.new("a")
là sự thật.