2012-01-30 7 views
2

이것은 Overload each method with order에 게시 된 질문과 비슷하지만 재정의하지 않고 지원되는 모든 관련 열거 형 메서드를 지원하려는 차이점이 있습니다.각 주문에 ***을 오버로드하여 원하는 순서를 설정하는 방법

내가 그들 각각을 다시 정의없이 열거가 제공 및 모든 관련 메소드를 오버라이드 (override) 어떻게하는 믹스 인을 사용. 예를 들어 :

module Ordering 
    def self.included base 
     base.class_eval do 
      alias_method :old_each,:each 

      def each *args,&block 
       reverse.old_each(*args,&block) # sample: just reverse std order 
      end 
     end 
    end 
end 

class OrderedArray < Array 
    include Ordering 
end 

a=OrderedArray.new [1,2,3] 
a.each{|_| p _} # works nicely 
p a.collect  # fails! 

를 생성 :

3 
2 
1 
[1, 2, 3] 

재정의 각수집 재정의 한 것으로 보이지 않는다!

+0

'Enumerable # collect'는'each' 메소드를 존중하지 않는 자체 구현으로'Array'에서 오버라이드됩니다. –

답변

0

당신은 또한 같은 순서를 반환하도록 비교 연산자 (<=>를) 재정의해야하고, 또한 클래스 include Enumerable.

+0

'Enumerable' 모듈은 이미'Array'에 포함되어 있습니다. 그리고'<=>'은'min'이나'sort'와 같은 메소드에서만 필요합니다. –

+0

@AShelly & @ -KL-7 : 제공된 예제에서 각 ***을 기본 주문 순서를 수정하는 데 전문으로하고 있지만 _implicit_ 필터링 (즉, 모든 * nil * 항목 삭제)을 적용하는 것이 바람직 할 수 있습니다. 다시 모든 _enumeration_ 메소드를 재정의하고 싶지 않습니다. – DMisener

+1

'each'와'<='를 오버라이드하는 것은 대부분의 클래스에 모든 열거 메소드를 제공하기에 충분해야합니다. Array는'each'를 우회하는 이들 메소드의 커스텀 구현을 가지고 있기 때문에,'Array'에서 파생 된 당신의 예제 클래스는 다른 것처럼 보입니다. (아마도 최적화 목적으로). 아마도 당신은 위임 대신 배열 위임을 시도 할 수 있습니다. – AShelly