2012-11-09 39 views
8

Đối với các loại biến số khác, tôi sử dụng ||=, nhưng điều này không hoạt động đối với các phép toán (x ||= true gán x thành true ngay cả khi x đã được gán cho sai).Làm cách nào để bạn đặt giá trị mặc định boolean trong Ruby?

tôi nghĩ rằng điều này sẽ làm việc:

x = true unless defined?(x) 

Nhưng nó không: nó gán x để nil đối với một số lý do. (Giải thích về đây sẽ được đánh giá.)

tôi biết một phương pháp mà làm việc:

unless defined?(x) 
    x = true 
end 

Nhưng nó khá dài dòng. Có cách nào ngắn gọn hơn để gán giá trị mặc định cho các biến boolean trong Ruby không?

+0

là có một lý do tại sao bạn không muốn x được gán để nil (tương đương với giả cho tất cả các ý định và mục đích)? –

+0

@ sylvain.joyeux Bởi vì anh ta muốn nó là "đúng", không phải là falsey. –

+0

@ sylvain.joyeux Sử dụng nil thay vì false là tốt, nhưng nó không giải quyết được sự cố với '|| ='. Nếu bạn cố gắng gán một giá trị mặc định cho x bằng cách sử dụng '|| =', và x trước đó được gán cho nil, nó sẽ bị ghi đè thay vì giữ lại giá trị của nil (vì nil là falsey). – evanrmurphy

Trả lời

10

Bạn phải có defined?đầu tiên, nếu không phân tích cú pháp đạt x = và sau đó xác định x (mà làm cho nó nil) trước khi chạy unless:

defined?(x) or x = true 
x #=> true 
x = false 
defined?(x) or x = true 
x #=> false 

Làm một khối if/unless (thay vì post- if/unless một lớp lót) cũng hoạt động:

unless defined?(x) 
    x = true 
end 
x #=> true 
x = false 
unless defined?(x) 
    x = true 
end 
x #=> false 
+0

Bạn đánh tôi lại với cú đấm lần nữa với cùng một [câu trả lời] (http://stackoverflow.com/questions/12614805/weird-ruby-behaviour/12615158#12615158) một lần nữa với một lời giải thích tốt hơn. – sunnyrjuneja

+0

@SunnyJuneja Tôi biết tôi đã viết một điều gì đó về điều này gần đây ... –

+0

Cảm ơn, Andrew. 'được xác định? (x) hoặc x = true' hoạt động tốt. – evanrmurphy

1

Chỉ có hai giá trị không đúng trong Ruby: falsenil. Tất cả những gì bạn cần làm là phân biệt giữa những thứ đó. Cho đến khi //= điều hành mới mà thực hiện điều này tự động đến xung quanh, bạn đang mắc kẹt với điều này:

if (x.nil?) 
    x = true 
end 

Hy vọng rằng điều này có thể được viết tắt trong các phiên bản tương lai của ruby. 99% thời gian bạn không thực sự quan tâm đến sự khác biệt giữa hai giá trị không đúng, nhưng 1% thời gian bạn làm điều đó trở nên gây phiền nhiễu khi phải được tiết lộ một cách bất thường.

Hãy nhớ rằng toán tử defined? sẽ luôn trả lại "local-variable" cho điều kiện đó vì biến số x được "xác định" làm biến cục bộ. Tương phản với defined?(nope) và bạn sẽ nhận được nil vì biến đó không tồn tại. Ruby quan tâm đến biến hoặc hằng số được đề cập, không phải nếu biến hoặc hằng số đó là được định nghĩa với một giá trị.

+4

Hoặc 'x = true nếu x.nil?', Mà đối với tôi thì dễ đọc hơn cả '|| =' thành ngữ! – Gene

+0

Tôi biết điều này có vẻ hiển nhiên nhưng bạn cần phải có 'x' ở đâu đó trong mã của bạn bởi vì 'lớp A; def self.check; nếu x.nil?; x = true; kết thúc; kết thúc; kết thúc; A.check; 'sẽ trả về một ngoại lệ' undefined local variable'. – sunnyrjuneja

+0

Tùy thuộc vào cotext của poster, điều này thực sự có thể sai. Nếu bạn làm điều này trong IRB, nó gây ra một 'undefined local variable' exception trong trường hợp ví dụ làm việc của poster không và gán' x = true'. – sunnyrjuneja

-1
x = defined?(x) ? true : false 
+0

-1 Điều này sẽ làm cho 'x' là' false' ngay cả khi nó đã là 'true'. –

+0

@AndrewMarshall có phải bạn muốn nói rằng nó sẽ làm cho 'x' thành' true' ngay cả khi nó đã là 'sai'? – evanrmurphy

+0

@evanrmurphy Vâng, tôi đã đảo ngược cả hai. –

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