Question

Ok, so I am working on a school assignment in Smalltalk and basically the gist of it is that I am writing 3 classes that "manually" set and override methods. The class MyObject is wrapped in another class, ManualTracer, which inherits from ObjectTracer.

MyObject contains a class variable, manualSet, which is a set of Symbols designating which methods were assigned to it manually, i.e. overriding inheritance. This set it declared using the class method manualSet: that accepts a Set of symbols. My problem is that I need this manualSet to filter OUT the set it receives based on the following criteria:

  1. Not in the inheritance chain (as a non-manual method, up to and including MyObject).
  2. Not actually a manual method.(checked by a method isManual)
  3. An actual manual method, but a parent (including ancestor) class already has that method (either by inheriting it specifically, or by overidding it).

Manual methods are checked by containing the comment "@Manual" in the source code.So far my code looks like this:

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.
]

So the "super" obviously isn't good enough, I need to go through ALL the ancestors, not just the parent. I also need to go through the comments of ALL ancestors and determine if they contain "@Manual". Any help would be GREATLY appreciated, thanks you!

Was it helpful?

Solution

You can use allSuperclasses method to get all ancestors. For example:

Integer allSuperclasses

will return

an OrderedCollection(Number Magnitude Object ProtoObject)

Then you can use allSatisfy: aBlock to see if they don't have this method.

I think that your code will look like this then:

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.
]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top