opDispatch shadowing toString - feature or bug?

Timon Gehr timon.gehr at gmx.ch
Thu Sep 1 04:59:29 PDT 2011


On 09/01/2011 09:34 AM, Damian Ziemba wrote:
> Greetings.
>
> I've been playing around with opDispatch and toString methods and I found
> strange behavior.
>
> Example:
>
> 	import std.stdio;
>
> 	struct Test
> 	{
> 		string opDispatch( string key )()
> 		{
> 			return "I am dispatching in struct!";
> 		}
>
> 		string toString()
> 		{
> 			return "I am Test struct!";
> 		}
> 	}
>
> 	class Test2
> 	{
> 		string opDispatch( string key )()
> 		{
> 			return "I am dispatching in class!";
> 		}
>
> 		string toString()
> 		{
> 			return "I am Test class!";
> 		}
> 	}
>
> 	void main()
> 	{
> 		Test test = Test();
> 		writeln ( test.s ); // I am dispatching in struct!
> 		writeln ( test.s() ); // I am dispatching in struct!
> 		writeln ( test ); // NOTHING :( But should return "I am
> Test struct!"
>
> 		Test2 test2 = new Test2();
> 		writeln ( test2.s ); // I am dispatching in class!
> 		writeln ( test2.s() ); // I am dispatching in class!
> 		writeln ( test2 ); // NOTHING :( But should return "I am
> Test class!"
> 	}
>
> Is it a feature or a bug?
>
> Best regards,
> Damian Ziemba
>

static assert(isInputRange!Test);
static assert(isInputRange!Test2);

toString is not shadowed, but the implementation of writeln assumes that 
your types are an InputRange (they provide, by the means of opDispatch, 
front(), empty() and popFront())

The fact that writeln([]); prints a new line instead of "[]" is a bug 
that has already been taken care of in a pull request afaik.

This specific problem can be solved by making your types not follow the 
InputRange interface, by putting an appropriate constraint on your 
opDispatch.


import std.stdio;

struct Test
{
	string opDispatch( string key )() if(key!="popFront")
	{
		return "I am dispatching in struct!";
	}

	string toString()
	{
		return "I am Test struct!";
	}
}

class Test2
{
	string opDispatch( string key )() if(key!="popFront")
	{
		return "I am dispatching in class!";
	}

	string toString()
	{
		return "I am Test class!";
	}
}

void main()
{
	Test test = Test();
	writeln ( test.s ); // I am dispatching in struct!
	writeln ( test.s() ); // I am dispatching in struct!
	writeln ( test ); //I am Test struct!
	
	Test2 test2 = new Test2();
	writeln ( test2.s ); // I am dispatching in class!
	writeln ( test2.s() ); // I am dispatching in class!
	writeln ( test2 ); // I am Test class!
}










More information about the Digitalmars-d-learn mailing list