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