2013-07-16 2 views
1

개체 비교를 포함하여 여러 가지 예상 시나리오에 대해 내 클래스를 complete으로하고 싶습니다. 내 수업은 Hash입니다. 그 방법에는 to_hash이라는 방법이 있는데, 여기에는 많은 수업 완수 방법이 있습니다. 예를 들어 :코어 클래스 비교 방법을 확장하는 가장 좋은 방법

class Hash 
    def == other 
    # Flip the comparison 
    other.is_a?(Hashlike) ? other == self : super 
    end 
end 

이 완전히 관련이없는 문제에 대한 모든 곳에서 스택 추적에서 종료됩니다 :

class Hashlike 
    def == other 
    if other.respond_to?(:to_hash) 
     to_hash == other.to_hash 
    end 
    end 
end 

이 과잉 바로 메시지의 superchain에 유사성을 주입하는 Hash#==을 대체 할 것으로 보인다. 이것은 침략적이라고 느낍니다.

Hash은 (는) Hashlike의 비교 대상인지 알고 싶거나 덜 침해받는 방법이 있습니까? 그리고 일반적으로 핵심 객체 (Hash, Array)를 확장하여 핵심 인터페이스 메시지 (==, nil?, <==>)를 수신하고 자신의 슈퍼 체인 전체에 지문을 남기지 않고 사용자 정의 클래스를 인식하는 규칙이 있습니까?

업데이트 :

나를 무시 호출 초기 조건 분기와 잠재적으로 많이 사용되는 방법을 질식하지 않는 희망 슈퍼 첫번째 수 있도록하는 것입니다에 발생하는 경우에만 최적화 :

class Hash 
    def == other 
    # Lazily delay the comparison 
    super or (other == self if other.is_a?(Hashlike)) 
    end 
end 

벤치마킹 (약 10 억 번의 비교)을 통해 두 접근법 모두를 사용하면 수신 된 객체에 to_hash이 정의되어 있으면 루비의 기본값을 반대로 수행한다는 것을 알 수 있습니다. 아래 답변에 나와 있습니다.

답변

1

해시는 이미이 작업을 수행합니다. 객체가 to_hash에 응답하면 Hash#==other == self을 수행해야합니다.