2009-04-20 3 views
3

나는 eql을 알고 있는가? 대신 == 객체가 키 *을 일치하는지 확인하기 위해 해시에 의해 사용, 당신은 당신이 == 연산자를 지원하려면 Ruby가 == AND eql을 갖고있는 좋은 이유는 무엇입니까? ? (to_a 및 to_ary와 유사)

def ==(rb) 

을하지만 해시는 사용하지 않는 것이 좋은 이유가 있어야한다 . 왜 그런가요? 언제 ==와 eql에 대한 정의를 가지고 있습니까? 이 아니고 상당 (예 : 다른 하나의 별칭)?

마찬가지로 to_a 외에 to_ary가 있어야하는 이유는 무엇입니까?

이 질문은 answer에 대한 응답으로 누군가 another question에게 저를주었습니다.

* 물론 해시도 eql을 사용하고 있습니까? == true는 해시 코드가 동일 함을 의미합니다.

또한 기본적으로 동일한 것을 재정의하는 것이 끔찍한 생각입니까? ?

+0

가능한 복제본은 무엇입니까 [동일합니까?, eql ?, === 및 ==?] (http://stackoverflow.com/questions/7156955/whats-the-difference-between-equal-eql - 및) – jtbandes

답변

9

루비에서이 특정 선택에 대한 추론을 모르겠다. 그러나 나는 평등이 어려운 개념이라는 것을 지적하겠다.

CL의 예는 당량, EQL, 동등 equalp하고, 그 문제를 = 갖는다위한

동일한 목적으로 두 개의 다른 물체를 두 개의 참조를 구별 할 수있는 것이 매우 유용 동일한 값을 가진 두 객체, 다른 유형의 두 객체 등이 있습니다. 얼마나 많은 변형이 의미가 있는지는 언어에서 의미가 무엇인지에 달려 있습니다. 나는 (내가 루비를 사용하지 않음) 제대로 기억하는 경우

, rubys 술어는 이러한 경우

의 세 가지를 구현 == 가치의 평등

EQL은? 값과 형의 동등 함

은 같은가? 는 동일한 개체에 대한 사실이다

+0

나는이 대답에 대해 실제로 생각해 볼 수 있습니다. 지금까지 게시 된 것들 중에서이 것이 가장 직접적으로 "왜 구별인가"라는 질문에 대한 답입니다. 이것은 제가 찾고있는 것입니다. 다른 사람들은 "차이점은 무엇입니까?" 나는 또한 일반적인 언어 디자인 문제를 지적하는 방법을 좋아한다. 실제로, 평등에 관해서는 눈보다 더 많은 것이 있습니다! – allyourcode

13

== 두 값이 같은지 확인 == eql? 동일한 유형인지 여부를 확인합니다.

irb(main):001:0> someint = 17 
=> 17 
irb(main):002:0> someint == 17 
=> true 
irb(main):003:0> someint.eql? 17 
=> true 
irb(main):004:0> someint.eql? 17.0 
=> false 
irb(main):005:0> someint == 17.0 
=> true 
irb(main):006:0> 

위에서 볼 수 있듯이, eql? 두 값이 같은 유형인지 테스트합니다. anyint가 부동 소수점 값이 아니기 때문에 false와 같은 17.0과 비교하는 경우입니다.

0

거기 해시 최고 (to_a)에 대한 to_ary 방법입니다,하지만 것 같다 Array 클래스, to_a과 다른 행동이 to_ary :

to_a :

자기를 반환합니다. Array의 서브 클래스에서 호출 된 경우 수신자를 Array 객체로 변환합니다.

는 to_ary :

자체를 돌려줍니다.

3

This는 to_a 및 to_ary (그리고 그리고 to_s 및 to_str 및 to_i 및 to_int)이 엄격의 다른 수준을 가지고 있음을 언급하고있다. 예를 들어,

17.to_s 

17.to_str 

하지 않습니다, 의미가 있습니다.

+0

링크를 제공해 주셔서 감사합니다. 나는 아직도 확신하지는 않지만, 추론의 일부를 설명한다. 또한 나는 당신이 "Ruby_에 맞는"것을 의미한다고 생각합니다. 나에게 그것은 17.to_s는 작동하지만 17.to_str은 작동하지 않는다는 것은 거의 이해가되지 않는다. – allyourcode

+1

to_s/to_a/to_f/to_i는 모두 명시적인 전환입니다. to_str/to_ary/to_int는 모두 암시 적 변환입니다. 예를 들어, 필자가 작성한 URI 라이브러리가 있습니다. 내 URI 클래스는 to_str을 구현합니다. String 형식의 URI를 매개 변수로 사용하는 메서드가 있으면 매개 변수로 전달하기 전에 URI 개체를 String으로 명시 적으로 변환하지 않아도되기 때문입니다. to_str 메서드를 사용하면이 작업을 수행 할 수 있습니다. –

0

위의 답변은 위의 답변보다 eql?이지만 여기는 to_ato_ary에 대한 내용입니다. Ruby의 duck-typing 체계에서 객체는 느슨하고 단단하게 두 가지 방식으로 변환 될 수 있습니다. 느슨한 변환은 다음과 같습니다. foo 자체를 배열 (to_a)로 나타냅니다. 이것은 to_a, to_s, to_i 및 기타 단일 문자를위한 것입니다. 따라서 String은 자신을 배열로 나타낼 수 있으므로 to_a을 구현합니다. 회사 변환은 매우 다른 것을 말합니다. foo은 문자열 (to_ary)입니다. 이것은 foo의 클래스가 헷갈리는 것이 아니라, foo와 문자열이 이 교환 가능하다는 것을 의미합니다. - 문자열이 예상되는 곳이면 foo를 논리적으로 사용할 수 있습니다. 내 루비 책의 예는 로마 숫자 클래스입니다. 우리는 양수를 사용할 수있는 곳이면 로마 숫자를 사용할 수 있으므로 Roman은 to_int을 구현할 수 있습니다. 이있는 클래스는 교환 가능합니다. 관계는 회사 변환을 구현해야하며, 느슨한 것은 거의 모든 클래스에 적용됩니다. 해석기에 내장 된 느슨한 코드가 심각한 오해를 유발할 수 있으며, C++의 reinterpet_cast<>에 필적하는 버그로 끝날 것입니다. 안좋다.