Object.toString, toHash, opCmp, opEquals

Timon Gehr timon.gehr at gmx.ch
Fri Apr 26 14:00:11 UTC 2024


On 4/26/24 08:44, Walter Bright wrote:
> Perhaps I can help things work for you and Timon:
> 
> ```
> import std.stdio;
> 
> class A
> {
>      string xxx(const Object) const { return "A"; }
> }
> 
> class B : A
> {
>      alias xxx = A.xxx;
>      string xxx(Object) { return "B"; }
> }
> 
> void main()
> {
>      const A a = new A();
>      B b = new B();
>      const B c = new B();
>      writeln(a.xxx(a));
>      writeln(b.xxx(b));
>      writeln(c.xxx(c));
> }
> ```
> I'm calling this xxx instead of toString, just so I can show all the 
> code. Compiling it and running it prints:
> 
> A
> B
> A
> 
> In other words, you can have a toString() that is mutable and it will 
> work fine with writeln(), because writeln(x) does not look for 
> Object.toString(), it looks for x.toString().
> 
> Does this work for you?

It clutters the user code with aliases. Might be preferable to forking 
Phobos though. Also, it can give wrong results at runtime.

For example, if a templated library type uses DbI to check whether it 
should make `toString` `const` by checking whether there is a `const 
toString` on the argument type, it will find `Object.toString`. Then 
those types will not properly compose with my `toString`.

This is not a theoretical problem either. This kind of introspection 
would be the proper fix for the following issue with 
std.typecons.Tuple.toString:

```d
import std.stdio, std.typecons;
class C{
     override string toString()=>"correct";
}

void main(){
     writeln(new C()); // "correct"
     writeln(tuple(new C())); // "Tuple!(C)(const(tt.C))"
}
```

This is also the same issue that prevents tuples with range members from 
being printed properly.




More information about the Digitalmars-d mailing list