subclassing

spir denis.spir at gmail.com
Tue Nov 2 07:04:52 PDT 2010


Hello,


After the exchanges on ranges, I am experimenting around this notion as a way to learn about D classes, subclassing, generics, etc...
In the code below, there are three obscure points for me:

* I wrote Range as class, but I rather meant an interface. D does not let me do that, apparently because there is no data slot in a D interface. Is then an interface a kind of data-less superclass? Or is there something I misunderstand?

* Why does D allow me redefining (data) slots in the subclass OddSquares, which exist in the superclass? (I did this first without noting, by copy & paste ;-)

* There is a bug in function find -- see DEBUG lines in this func and in main. For any reason, the passed range loses its data (.element==0). If I change find's interface to take a range of type OddSquares, then all runs fine. I don't know what more to do to find the bug...

(I hope you don't mind spaces before ';', I like to put purely syntactic thingies aside from proper code.)


Thank you for your help,
Denis

PS: I like very much this interface for input ranges :-) Decided to make output data plain state (slots T element & bool continues); only step() is a method. I know this is not true OO for some conception of OO, but it is ok for me. I also like in this design the fact that the constructor sets the range's initial state -- or is supposed to -- so that we can use the range at once, without calling step() once to initialise it.
Iteration using for as shown below is indeed equivalent to:
	auto range = ...;
	while (range.continues) {
		doSomethingWith(range.element);
		range.step();
	}
which is analog to traditional list traversal using
	while (node.next) {
		doSomethingWith(node.element);
		node = node.next;
	}
except the range interface can be applied to any kind of collection, taken globally or partially, even virtual like in the example of OddSquares below.


=================== code ======================
/+  experimentation on notion of range
+/

import std.stdio ;      // write*
import std.string ;		// join , format
import std.conv ;		// to!(destType)(expression)

class Range(T) {
    alias T type ;          // meta info
    // external state
    T element ;
    bool continues ;
    // methods
    abstract void step() ;
}

class OddSquares(T) : Range!T {
    alias T type ;          // meta info
    // external state
    T element ;
    bool continues ;
    // internal state
    private T number ;
    private T max ;
    // methods
    override void step() {
        if (this.number > this.max) {
            // continues range...
            this.continues = false ;
        } else {
            // ... or step once
            this.continues = true ;
            this.element = this.number * this.number ;
            this.number += 2 ;
        }
    }
    this(T min, T max) {
        // set initial internal state
        if (min%2 == 1)
            this.number = min ;
        else
            this.number = min+1 ;
        this.max = max ;
        // set initial external state
        this.step() ;
    }
}

T find (T) (OddSquares!T range , bool function(T element) predicate) {
    T element ;
    writeln("***", range.element) ;    // DEBUG
    for (; range.continues ; range.step) {
        element = range.element ;
        writeln(element) ;
        if (predicate(element))
            return element ;
    }
    return 0 ;  // placeholder, should be throw Exception
}

void main() {
    OddSquares!int range ;
    int element ;
    // traversal
    range = new OddSquares!int(1,9) ;
    writef ("elements of type %s: ", typeid(range.type)) ;
    for (; range.continues ; range.step) {
        element = range.element ;
        writef("%s ", element) ;
    }
    writeln() ;
    // find
    range = new OddSquares!int(10,20) ;
    writeln("***", range.element) ;    // DEBUG
    element = find!int(range, function bool(int e){return (e>200 && e<250);}) ;
    writeln("found element: ", element) ;
}

================== output =====================
=== buggy
elements of type int: 1 9 25 49 81 
***121
***0
found element: 0

=== correct
elements of type int: 1 9 25 49 81 
***121
***121
found element: 225
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



More information about the Digitalmars-d-learn mailing list