2009-02-25 11 views

Trả lời

12

Thứ nhất, tôi không nghĩ rằng shortcircuiting có thể hợp lý áp dụng cho XOR: bất kể giá trị của toán hạng đầu tiên, thứ hai cần phải được kiểm tra.

Thứ hai và, & & hoặc || sử dụng shortcircuiting trong mọi trường hợp; sự khác biệt duy nhất giữa các phiên bản "từ" và "biểu tượng" là ưu tiên. Tôi tin rằng andor có mặt để cung cấp các chức năng tương tự như perl có trong dây chuyền như

process_without_error or die 

Tôi nghĩ lý do vì không có một xor tên chức năng có lẽ là không có điểm trong một nhà điều hành-ưu tiên thấp trong trường hợp này và rằng nó đã là một tình huống đủ khó hiểu!

+0

Tôi nghĩ rằng "không có điểm trong ưu tiên thấp' xor' chức năng "là không đúng. Trong Perl tôi đã được sử dụng để kiểm tra hai thông số CGI độc quyền với một cái gì đó như 'param1 xor param2'. Xấu hổ tôi cần phải làm điều này một cách phức tạp hơn trong Ruby. – geronime

+1

Ngày nay, tôi đồng ý về 'và' và' hoặc' là luồng điều khiển. Avdi đã viết về nó tại http://devblog.avdi.org/2010/08/02/using-and-and-or-in-ruby/ (trên thực tế, tôi liên kết với câu hỏi này trong phần bình luận của bài đăng trên blog) –

17

Không, bạn chỉ có thể sử dụng ^.

Không biết tại sao không có gì đặc biệt, có thể chỉ vì nó không được sử dụng phổ biến.

+1

'^ 'chạy vào các vấn đề với các giá trị truthy. Tôi đã xác định chức năng của riêng mình: – John

+0

Tôi vừa mới bị ảnh hưởng bởi điều này. Tôi đang sử dụng ruby-prof để cải thiện thuật toán và tôi nghĩ rằng việc đơn giản hóa một số điều kiện với XOR sẽ làm cho nó nhanh hơn. Nhưng đó là cách khác. – Papipo

+0

Xin lỗi vì không được chấp nhận, nhưng tôi thích câu trả lời của Mike ngày nay. –

10

Hãy thử ^

true^false #=> true 
true^true #=> false 
false^false #=> false 

Không đồng bằng toán tử tương đương tiếng Anh mặc dù.

14

Tôi chạy vào một vấn đề vì '^' điều hành hoạt động Bitwise trên con số,

true^1 
=> false 

1^true 
TypeError: can't convert true into Integer 
true^1 

nên workaround của tôi là:

(!!a^!!b) nơi đôi-bang buộc họ vào các phép toán luận.

!!1^!!true 
=> false 

!!1^!!false 
=> true 
+1

Thú vị, nhưng không liên quan đến câu hỏi. – Macha

+1

++ Hữu ích. Tôi đến đây tìm kiếm XOR, nhưng biết làm thế nào để làm ngược lại, đó là, ép buộc một bool to_i? Toán hạng khác của tôi đã là một int, và tôi cần kết quả là int. – Marcos

+0

@Macha + 1ing vì tôi vừa gặp vấn đề tương tự, và không có câu hỏi nào khác về xâu boolean của Ruby không phải về chuỗi. –

1

Bất kỳ việc triển khai xor sẽ không cho phép đoản mạch. Cả hai biểu thức cần phải được đánh giá không có vấn đề gì.

Ruby cung cấp toán tử ^, nhưng điều này sẽ làm thay đổi giá trị trung thực. Tôi đã thực hiện một chức năng để xử lý các trường hợp tôi muốn một xor mà ứng xử giống như andor:

def xor(a,b) 
    (a and (not b)) or ((not a) and b) 
end 

Không giống như ^, chức năng này có thể được sử dụng trong những tình huống tương tự như sau:

xor("hello".match(/llo/), false) # => true 
xor(nil, 1239)     # => true 
xor("cupcake", false)   # => false 
+1

Câu trả lời/nhận xét của Chris Phoenix về 'xor (" cupcake ", sai)' trả lại đúng là chính xác. –

2

Câu trả lời của John có vẻ không chính xác. Trong irb với 1.9.3, xor ("cupcake", false) trả về true, như bạn mong đợi.

1.9.3-p429 :104 > def xor(a,b) 
1.9.3-p429 :105?>  (a and (not b)) or ((not a) and b) 
1.9.3-p429 :106?> end 
=> nil 
1.9.3-p429 :107 > xor(false, true) 
=> true 
1.9.3-p429 :108 > xor("cupcake", false) 
=> true 
6

Là một thay thế để lừa phủ đôi Matt Van Horn cho sử dụng XOR trên các loại tùy ý, bạn có thể chuỗi một thử nghiệm XOR, bắt đầu với nil. I E.:

!!foo^!!bar 

tương đương với

nil^foo^bar 

này trông gọn gàng để mắt của tôi, và tôi cho rằng đòi hỏi một hoạt động ít logic

+0

Giải pháp tốt –