January 07, 2005
import std.stream;

class MoreObjectionable : Objectionable {
    override uint toHash() {
		stdout.writeLine("gotcha! 3, 4, 5 ...");
		return super.toHash();
	}

    override char[] toString() {
		stdout.writeLine("gotcha! 2");
		return super.toString() ~ "null ptr";
	}

private:
	int opEquals(Object o) {
		stdout.writeLine("gotcha! 1");
		return -1;
	}
}

class Objectionable : Object {
	alias MoreObjectionable.toHash toHash;
	override char[] delegate() toString = null;
private:
	int opEquals(Object o) {
		stdout.writeLine("gotcha! 1");
		return -1;
	}
}

int main(char[][] args) {
	int[MoreObjectionable] aa;
	MoreObjectionable mo = new MoreObjectionable();
	Object o = mo;
	if( o == mo ) { args[0] = "once"; }
	if( mo == o ) { args[0] = "twice"; }
	// comment out toString() for endless loop
	mo.toString();
	aa[mo] = 1;
	return 0;
}

/*

1) (cast(BaseClass)).function() != DerivedClass.function
2) toString() obliterated
3) Using 'alias' allows cyclic inheritance graphs
4) What's so great about acyclic inheritance graphs anyway?
5) goto 3)

*/