Thread overview
toString best practices
Feb 09, 2023
Paolo Invernizzi
Feb 15, 2023
Bastiaan Veelo
Feb 17, 2023
Paolo Invernizzi
February 09, 2023
Hello everybody,

Let's assume there's an implementation of a templated struct like this:

```
import std.format, std.range.primitives;

struct Point(T)
{
    T x, y;

    void toString(W)(ref W writer, scope const ref FormatSpec!char f) const
    if (isOutputRange!(W, char))
    {
        put(writer, "(");
        formatValue(writer, x, f);
        put(writer, ", ");
        formatValue(writer, y, f);
        put(writer, ")");
    }
}

void main(){

        import std.format : format;
        assert( format("%s", Point!int(1,2)) == "(1, 2)");

    	import std.experimental.logger;
    	sharedLog.infof("%s", Point!int(1,2));
/+
 Error: none of the overloads of template `std.logger.core.Logger.memLogFunctions!LogLevel.info.logImplf` are callable using argument types `!()(string, Point!int) shared`
/Users/pinver/dlang/dmd-2.102.0/osx/bin/../../src/phobos/std/logger/core.d(828,14):        Candidates are: `logImplf(int line = __LINE__, string file = __FILE__, string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__, string moduleName = __MODULE__, A...)(lazy bool condition, lazy string msg, lazy A args)`
/Users/pinver/dlang/dmd-2.102.0/osx/bin/../../src/phobos/std/logger/core.d(876,14):                        `logImplf(int line = __LINE__, string file = __FILE__, string funcName = __FUNCTION__, string prettyFuncName = __PRETTY_FUNCTION__, string moduleName = __MODULE__, A...)(lazy string msg, lazy A args)`
+/

}
```

What is the best way to handle also shared writers?

Thank you all,
Paolo




February 15, 2023

On Thursday, 9 February 2023 at 17:49:58 UTC, Paolo Invernizzi wrote:

>
import std.format, std.range.primitives;

struct Point(T)
{
    T x, y;

    void toString(W)(ref W writer, scope const ref FormatSpec!char f) const
    if (isOutputRange!(W, char))
    {
        put(writer, "(");
        formatValue(writer, x, f);
        put(writer, ", ");
        formatValue(writer, y, f);
        put(writer, ")");
    }
}

void main(){

        import std.format : format;
        assert( format("%s", Point!int(1,2)) == "(1, 2)");

    	import std.experimental.logger;
    	sharedLog.infof("%s", Point!int(1,2));
}

Pasting this into https://run.dlang.io/, it just works. That's for DMD 2.099, so it might be a regression -- or recent feature?

-- Bastiaan.

February 17, 2023
On Wednesday, 15 February 2023 at 12:15:18 UTC, Bastiaan Veelo wrote:
> On Thursday, 9 February 2023 at 17:49:58 UTC, Paolo Invernizzi wrote:
>> ```
>> import std.format, std.range.primitives;
>>
>> struct Point(T)
>> {
>>     T x, y;
>>
>>     void toString(W)(ref W writer, scope const ref FormatSpec!char f) const
>>     if (isOutputRange!(W, char))
>>     {
>>         put(writer, "(");
>>         formatValue(writer, x, f);
>>         put(writer, ", ");
>>         formatValue(writer, y, f);
>>         put(writer, ")");
>>     }
>> }
>>
>> void main(){
>>
>>         import std.format : format;
>>         assert( format("%s", Point!int(1,2)) == "(1, 2)");
>>
>>     	import std.experimental.logger;
>>     	sharedLog.infof("%s", Point!int(1,2));
>> }
>> ```
>
> Pasting this into https://run.dlang.io/, it just works. That's for DMD 2.099, so it might be a regression -- or recent feature?
>
> -- Bastiaan.

Hi Bastiaan,

I think the cause is in some change happened in the logger module, I'm recompiling some code with the latest dmd frontend.

I solved it simply using the 'logX' functions at module level instead of the sharedLog methods.

Thank you!