2012-09-15 37 views
6

Xin lỗi nếu bị trùng lặp (Tôi không tìm thấy)Có phải "==" trong Ruby luôn luôn có giá trị bình đẳng không?

Điều này chỉ để xác nhận rằng toán tử Ruby == luôn thực hiện so sánh bình đẳng. I.e.

a == b 

so sánh một giá trị so với giá trị b, thay vì hơn, như Java, cho dù họ trỏ đến cùng một đối tượng trong bộ nhớ (Đối với điều thứ hai này, trong Ruby, bạn nên sử dụng a.object_id == b.object_id).

Như vậy, kết quả là nó là an toàn để so sánh các giá trị chuỗi với == trong Ruby (trong khi nó không phải là an toàn để làm như vậy trong Java)

Cảm ơn

Sửa:

Câu hỏi đặt ra là hành vi mặc định == đối với bất kỳ đối tượng Ruby nào, vì nó có thể đánh lừa các lập trình viên Java-C-C++ giả sử một == b so sánh các tham chiếu, chứ không phải nội dung tham chiếu.

Dù sao, bạn có thể kiểm tra mã này, sử dụng chuỗi

one="hello" 
two="he" 
two << "llo" 

if one == two 
    puts "surprise: comparing values, not like in Java" 
end 

if not one.object_id == two.object_id 
    puts "obvious: do this to compare references" 
end 

Chỉnh sửa 2.

Vì vậy, trong Ruby, sự so sánh

a == b 

kiểm tra một và giá trị b của

nhưng, việc chuyển nhượng

a = b 

không sao chép giá trị, nhưng làm cho a và điểm b để cùng một đối tượng!

tiếp tục với mã trước

puts one.object_id 
puts two.object_id 

puts " and now " 

one = two 

puts one.object_id 
puts two.object_id 
+1

Có. http://stackoverflow.com/questions/1710369/most-concise-way-to-test-string-equality-not-object-equality-for-ruby-strings – nneonneo

+1

Liên kết được tham chiếu không trùng lặp câu hỏi này ... –

+0

Có điều đầu tiên tôi nhận ra là trong Ruby toán tử '==' và hàm 'equals' được đảo ngược với những gì nó được mong đợi trong C giống như ngôn ngữ. – EliuX

Trả lời

3

Trong Ruby, == có thể bị quá tải, vì vậy nó có thể làm bất cứ điều gì các nhà thiết kế của lớp bạn đang so sánh muốn nó làm. Về khía cạnh đó, nó rất giống với phương thức equals() của Java.

Quy ước dành cho == để so sánh giá trị và hầu hết các lớp tuân theo quy ước đó, bao gồm String. Vì vậy, bạn đã đúng, sử dụng == để so sánh các chuỗi sẽ làm điều mong đợi.

Quy ước dành cho equal? để so sánh tham chiếu, do đó, thử nghiệm a.object_id == b.object_id cũng có thể được viết a.equal?(b). (Phương pháp equal? có thể được định nghĩa để làm điều gì đó không chuẩn, nhưng sau đó một lần nữa, như vậy có thể object_id!)

(Side lưu ý:. Khi bạn thấy mình so sánh chuỗi trong Ruby, bạn thường cần phải có được sử dụng ký tự thay)

+0

Downvoter: hãy giải thích! Nếu có bất cứ điều gì sai với câu trả lời của tôi, tôi rất muốn được chiếu sáng :) – Thomas

1

Từ http://www.skorks.com/2009/09/ruby-equality-and-object-comparison/.

Mã:

class MyObject 
end 
object1 = MyObject.new 
object2 = object1 
object3 = MyObject.new 

puts "Object 1 is == to object 2: #{object1 == object2}" 
puts "Object 1 is eql? to object 2: #{object1.eql? object2}" 
puts "Object 1 is equal? to object 2: #{object1.equal? object2}" 
puts "Object 1 is == to object 3: #{object1 == object3}" 
puts "Object 1 is eql? to object 3: #{object1.eql? object3}" 
puts "Object 1 is equal? to object 3: #{object1.equal? object3}" 

Sản lượng:

Object 1 is == to object 2: true 
Object 1 is eql? to object 2: true 
Object 1 is equal? to object 2: true 
Object 1 is == to object 3: false 
Object 1 is eql? to object 3: false 
Object 1 is equal? to object 3: false 

Edit - đầu ra bổ sung:

irb(main):001:0> class MyObject 
irb(main):002:1> end 
=> nil 
irb(main):003:0> object1 = MyObject.new 
=> #<MyObject:0x281bc08> 
irb(main):006:0> object1.respond_to?('=='.to_sym) 
=> true 
irb(main):007:0> object1.respond_to?('eql?'.to_sym) 
=> true 
irb(main):013:0> MyObject.superclass 
=> Object 
+1

Điều này là gây hiểu lầm, bởi vì 'MyObject' không xác định bất kỳ phương pháp nào đúng cách. – Thomas

+0

Có nó ... xem chỉnh sửa ... –

+1

Bởi "đúng" tôi có nghĩa là "theo quy ước", đó là: 'bằng?' Không tham chiếu bình đẳng, 'eql?' Có giá trị bình đẳng, và '==' không bình đẳng giá trị với các loại chuyển đổi. Bài báo ở trên đã được trích từ (http://www.skorks.com/2009/09/ruby-equality-and-object-comparison/) giải thích rõ điều này, nhưng chỉ đoạn mã này thiếu ngữ cảnh thực sự trả lời câu hỏi . – Thomas

0

Theo t o "Ngôn ngữ lập trình Ruby" (Flanagan & Matsumoto), phần 4.6.7 trang 106

== là toán tử bình đẳng. Nó xác định xem hai giá trị có bằng nhau hay không, theo định nghĩa của toán hạng "bằng nhau" của toán hạng.

Và trong 3.8.3 trang 74:

Mỗi đối tượng có một nhận dạng đối tượng, một Fixnum, mà bạn có thể có được với phương pháp object_id. Giá trị trả về bởi phương thức này là không đổi và duy nhất cho toàn bộ thời gian của đối tượng.

Vì vậy, điều này làm việc ngược lại so với Java (bất ngờ với tôi).

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