2010-06-21 29 views
11

Tôi không hiểu đoạn mã sau (x!):nếu vs if (x == false) trong ruby ​​

ruby-1.9.1-p378 > puts "nil is false" unless nil 
nil is false 
=> nil 
ruby-1.9.1-p378 > puts "nil isn't false" unless nil == false 
nil isn't false 
=> nil 

Trong hầu hết các ngôn ngữ (của một C-base, ít nhất), if (! cond) và nếu (cond == false) đánh giá tương tự. Điều gì đang xảy ra ở đây để làm cho rằng không phải là trường hợp?

(Tôi muốn các chi tiết về việc tại sao, tôi hiểu rằng đó là cách nó được.)

Trả lời

31

Ruby cho rằng falsenil là hai giá trị "sai" duy nhất, trong khi mọi thứ khác là "trung thực". Điều này là theo định nghĩa và không thể sửa đổi (ít nhất là trong MRI). Định nghĩa này được sử dụng cho tất cả các nhà khai thác BUILTIN như if, unless, while, until, cond ? if_truthy : if_falsey, ||, && ...

Viết foo == bar sẽ luôn luôn gọi phương thức == trên foo với bar như một cuộc tranh cãi. Theo mặc định, nil, false, true và tất cả các biểu tượng khác giống như biểu tượng, v.v ..., chỉ bằng với chính chúng. Điều này có thể được thay đổi, mặc dù:

def nil.==(bar) 
    super || bar == false 
end 
puts "nil == false" if nil == false # => "nil == false" 

Trong Ruby 1.9, bạn cũng có thể xác định lại các nhà điều hành !, vì vậy unless foo không nhất thiết phải giống như if !foo hoặc ngược lại của if foo:

def true.! 
    true 
end 

puts "True?" if true # => "True?" 
puts "or not?" if !true # => "or not?" 

Không phải là bất kỳ ai cũng khuyên bạn nên làm bất cứ điều gì như thế này ...

+0

nil không * thực sự sai *, chỉ là * falsey *. Lời giải thích hoàn hảo. +1. Và có, xin đừng ghi đè == hoặc! hoặc bất cứ điều gì nếu bạn không có một lý do rất tốt. – MatrixFrog

+0

+1 để có câu trả lời hay. Điều tương tự cũng đúng trong PHP mà phải phát minh ra toán tử '===' (có nghĩa là * ba * '=') – Mawg

+0

Cảm ơn rất nhiều vì đã giải thích. –

2

nil không phải là bằng giả bằng cách so sánh trên == vì nội dung ngữ nghĩa của họ là khác nhau (nil là không có thông tin, false là một giá trị boolean). Tuy nhiên, nếu bạn cố gắng đánh giá nil trong ngữ cảnh boolean, nó sẽ được coi là Sai, chủ yếu là vì sự tiện lợi và khả năng tương thích thành ngữ với các ngôn ngữ khác.

nil == a <=> nil != a <=> false sẽ là trường hợp cho hầu như bất kỳ giá trị nào của ngoại trừ số không.

Vì vậy, bạn chỉ có thể biết rằng 'nil không đúng' và 'nil là không'. Đây là như xa như ruby ​​đi theo cách của nó.

0

Trong một số ngôn ngữ, bạn chỉ có thể sử dụng các toán tử trong câu lệnh "if". Cố gắng kiểm tra xem một chuỗi hoặc một số là đúng hay sai chỉ là ngớ ngẩn và vô nghĩa để ngôn ngữ không cho phép bạn làm điều đó.

Trong Ruby, tuy nhiên, mọi thứ có thể được coi là boolean, mặc dù nó thực sự không. Trong thực tế, mọi thứ trong Ruby đều đúng, ngoại trừ nil và false (IIRC). Điều đó không có nghĩa là nil thực sự là EQUAL thành false, cũng giống như nó không có nghĩa là số nguyên 45 thực sự là EQUAL thành true. Chúng khác nhau, riêng biệt, mọi thứ. Nhưng nếu bạn định đối xử với nil như một boolean (tức là sử dụng nó trong một hoặc nếu không) thì nó giống như là sai.

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