2013-05-08 2 views
3

Итак, я работаю над назначением школы в Smalltalk, и в основном суть этого заключается в том, что я пишу 3 класса, которые «вручную» устанавливаются и переопределить методы. Класс MyObject завернут в другой класс, ManualTracer, который наследуется от ObjectTracer.Как определить, установлен ли метод в классе предков объекта Smalltalk

MyObject содержит переменную класса manualSet, которая представляет собой набор символов, обозначающих, какие методы были назначены ему вручную, то есть переопределение наследования. Этот параметр объявлен с помощью метода класса manualSet: он принимает набор символов. Моя проблема заключается в том, что мне нужен этот manualSet, чтобы отфильтровать набор, которую она получает на основании следующих критериев:

  1. Не в цепочке наследования (как не ручным способом, вплоть до MyObject).
  2. На самом деле не ручной метод. (Проверено методом isManual)
  3. Фактический ручной метод, но у родительского (в том числе и предкового) класса уже есть этот метод (либо путем наследования его конкретно, либо путем его обложения).

Ручные методы проверены, содержащие комментарий «@Manual» в источнике code.So далеко мой код выглядит следующим образом:

manualSet: aSet 
| validatedSet | 
(aSet == nil) ifTrue: [ manualSet:= nil ] 
ifFalse: [ 
    (aSet isMemberOf: Set) ifFalse:[^nil]. 
    validatedSet:= aSet select:[ :each| (each isMemberOf:Symbol) 
            and:(self respondsTo:each) 
            and:(self isManual:each in: self) 
            and:((self isManual:each in:super)not)]. 
    manualSet:= validatedSet. 
] 

Таким образом, «супер», очевидно, не достаточно хорошо, Мне нужно пройти через ВСЕ предков, а не только родителей. Мне также нужно просмотреть комментарии всех предков и определить, содержат ли они «@Manual». Любая помощь была бы высоко оценена, спасибо!

ответ

5

Вы можете использовать метод allSuperclasses, чтобы получить всех предков. Например:

Integer allSuperclasses 

вернется

an OrderedCollection(Number Magnitude Object ProtoObject) 

Затем вы можете использовать allSatisfy: aBlock, чтобы увидеть, если они не имеют этот метод.

Я думаю, что ваш код будет выглядеть следующим образом, то:

manualSet: aSet 
| validatedSet | 
(aSet == nil) ifTrue: [ manualSet:= nil ] 
ifFalse: [ 
    (aSet isMemberOf: Set) ifFalse:[^nil]. 
    validatedSet:= aSet select:[ :each| 
     (each isMemberOf:Symbol) 
     and:(self respondsTo:each) 
     and:(self isManual:each in: self) 
     and:(self allSuperclasses allSatisfy: [:class | 
      (self isManual:each in:class) not])]. 
    manualSet:= validatedSet. 
] 
+0

О, Uko, что бы я без тебя. Вы всегда отвечаете на все мои вопросы. Благодаря! –

+0

О, также я закончил тем, что менял линию и: (self отвечает: Toto: each) to и: (self canUnderstand: each), потому что canUnderstand является синонимом класса sides ответа: но он обращается ко всем предкам через наследование класса ... хорошая идея или плохая идея, на ваш взгляд? –

+1

@WesField не проблема. Выполнение 'responsesTo: aSymbol':'^self class canUnderstand: aSymbol' – Uko