2010-06-12 69 views
99

Có vẻ như không thể tìm cách kiểm tra xem đối tượng có phải là một boolean dễ dàng hay không. Có thứ gì đó như thế này trong Ruby không?Kiểm tra xem đối tượng Ruby có phải là Boolean

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

Ngay bây giờ tôi đang làm điều này và muốn rút ngắn nó:

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

Tương tự: [check-dù-a-biến-là-a-chuỗi-trong-ruby?] (Http://stackoverflow.com/questions/7749416/check-whether-a-variable-is-a- string-in-ruby? rq = 1) – nawfal

Trả lời

113

Cách đơn giản nhất tôi có thể nghĩ:

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

lớp X; def; tự kết thúc; x = X.new; !! x == x # => true – Alexey

+5

Vâng, đó được gọi là gõ vịt và nguyên tắc cốt lõi của OOP. Tôi nghĩ đó là một tính năng. –

+1

Vấn đề với nó là "nếu nó đi như vịt" không ngụ ý "nó quacks như vịt". Tương ứng '!! pseudo_bool == pseudo_bool' không ngụ ý' pseudo_bool & true == pseudo_bool' chẳng hạn. – Alexey

77

Không có lớp Boolean trong Ruby, cách duy nhất để kiểm tra là để làm những gì bạn đang làm (so sánh đối tượng với truefalse hoặc lớp đối tượng chống lại TrueClassFalseClass). Không thể nghĩ ra lý do tại sao bạn sẽ cần chức năng này mặc dù, bạn có thể giải thích? :)

Nếu bạn thực sự cần chức năng này tuy nhiên, bạn có thể hack nó trong:

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

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

cố gắng làm typecasting dựa trên giá trị hiện tại. –

+57

'Tại sao bạn lại bao giờ làm điều đó?' (và các dẫn xuất) chỉ là một trong những câu hỏi khó chịu nhất mà một kỹ sư có thể tạo ra khác :) – vemv

+9

+1 vì tôi có thể sử dụng nó trong rspec như: 'expect (some_method? (dữ liệu)). be_a (Boolean)' – Automatico

19

Như đã trình bày ở trên không có lớp boolean chỉ TrueClass và FalseClass tuy nhiên bạn có thể sử dụng bất kỳ đối tượng như đề tài này nếu/trừ và mọi thứ đều đúng, ngoại trừ trường hợp của FalseClass và nil

kiểm tra Boolean trả về một thể hiện của các FalseClass hoặc TrueClass

(1 > 0).class #TrueClass 

Các monkeypatch sau để Object sẽ cho bạn biết một cái gì đó là một thể hiện của TrueClass hoặc FalseClass

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

Chạy một số xét nghiệm với IRB cung cấp cho các kết quả như sau

?> "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

Đơn giản chỉ để viết 'self == true hoặc self == false'. Đó là những trường hợp duy nhất của TrueClass và FalseClass. – Chuck

+0

@chuck trả về cùng một kết quả ngoại trừ Time.now.boolean? trả về nil. Bất kỳ ý tưởng tại sao? –

+0

Xác định một lớp học tự kiểm tra trong phương pháp này có phần không phải là oop. Bạn nên định nghĩa hai phiên bản 'boolean', một phiên bản cho TrueClass/FalseClass và một cho Object. –

5

Một đối tượng là một boolean hoặc sẽ có một lớp TrueClass hoặc FalseClass do đó một lớp lót sau sẽ thực hiện lừa

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

Sau đây cũng sẽ cung cấp cho bạn đúng/sai boolean loại kết quả kiểm tra

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

Nếu mã của bạn một cách hợp lý có thể được viết như một tuyên bố trường hợp, đây là khá tốt:

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

Vì vậy, hãy thử điều này ra (x == true)^(x == false) lưu ý bạn cần dấu ngoặc đơn nhưng điều này đẹp hơn và nhỏ gọn hơn.

Nó thậm chí vượt qua gợi ý như "cuak" nhưng không phải là một "cuak" ... class X; def !; self end end ; x = X.new; (x == true)^(x == false)

Note: Thấy rằng đây là rất cơ bản mà bạn có thể sử dụng nó trong các ngôn ngữ khác cũng vậy, mà không cung cấp một "điều là boolean".

Note 2: Ngoài ra bạn có thể sử dụng để nói điều là một trong những ??: "red", "green", "blue" nếu bạn add more XORS ... hoặc nói điều này là một trong những ??: 4, 5, 8, 35.

68

Tôi tìm thấy điều này là ngắn gọn và tự chủ tài liệu:

[true, false].include? foo 

Nếu sử dụng Rails hoặc ActiveSupport, bạn thậm chí có thể làm một truy vấn trực tiếp sử dụng in?

foo.in? [true, false] 

Kiểm tra chống lại tất cả các giá trị có thể isn 't một cái gì đó tôi muốn giới thiệu cho phao, nhưng khả thi khi chỉ có hai giá trị có thể!

+0

câu trả lời hay nhất cho đến nay, mặc dù tôi cũng thích' foo == true hoặc foo == false' mà ai đó đưa vào nhận xét. –

+0

Tôi thích điều này vì nó ít khó hiểu hơn so với '!! foo == foo'. – stringsn88keys

0

No. Không giống như bạn có mã của bạn. Không có bất kỳ lớp nào có tên Boolean. Bây giờ với tất cả các câu trả lời bạn có bạn sẽ có thể tạo ra một và sử dụng nó. Bạn biết làm thế nào để tạo ra các lớp học phải không? Tôi chỉ đến đây vì tôi chỉ tự hỏi ý tưởng này. Nhiều người có thể nói "Tại sao? Bạn phải biết Ruby sử dụng Boolean như thế nào". Đó là lý do tại sao bạn nhận được câu trả lời bạn đã làm. Vì vậy, cảm ơn câu hỏi. Thức ăn cho sự suy nghĩ. Tại sao Ruby không có một lớp Boolean?

NameError: uninitialized constant Boolean 

Hãy nhớ rằng các đối tượng không có loại. Họ là những lớp học. Đối tượng có dữ liệu. Vì vậy, đó là lý do tại sao khi bạn nói các loại dữ liệu đó là một chút nhầm lẫn.

Cũng thử rand 2 vì rand 1 dường như luôn cung cấp 0. rand 2 sẽ cho 1 hoặc 0 nhấp vào chạy một vài lần tại đây. https://repl.it/IOPx/7

Mặc dù tôi không biết cách tự tạo một lớp Boolean. Tôi đã thử nghiệm với nó nhưng ...

class Boolean < TrueClass 
    self 
end 

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

Ít nhất chúng tôi có lớp đó ngay bây giờ nhưng ai biết cách có được giá trị phù hợp?

Các vấn đề liên quan