Re: std.logger issue
On Thursday, 26 January 2023 at 17:17:28 UTC, o3o wrote: how can I enable `trace` level? Set `sharedLog.logLevel` instead of `globalLogLevel`. ```d // Note: the cast is needed because sharedLog is shared (cast()sharedLog).logLevel = LogLevel.all; ``` Explanation: logging functions (`trace`, `log`, etc.) called without a logger perform the logging using a global logger called `sharedLog`. `sharedLog` uses `LogLevel.info` by default, which is why your trace messages were not showing.
Re: what wrong with this alias
On Sunday, 8 January 2023 at 05:42:46 UTC, Qusatlegadus wrote: auto s = 1234.to!string.map!q{a - '0'}.sum; works fine. but if i do an alias alias comb = to!string.map!q{a - '0'} Error: unknown, please file report on issues.dlang.org What's wrong with this ## Simple explanation `to!string` is a function expecting 1 argument, which you're not providing in your alias. Convert your alias to a lambda expression: ```D alias comb = x => x.to!string.map!q{a - '0'} ``` ## Complicated explanation `to` is a template defined like this: ```D // https://github.com/dlang/phobos/blob/master/std/conv.d template to(T) { T to(A...)(A args) if (A.length > 0) { return toImpl!T(args); } // some overloads omitted for brevity } ``` `to` needs at least 2 template arguments - the first one for the outer template is passed explicitly (what you did with `to!string`), the other ones are inferred from the arguments passed to the `to` function. Since you did not pass an argument to `to!string`, the inner template doesn't get instantiated. Basically what happens is you're trying to pass an uninstantiated template as argument to `map`. This is quite an exotic situation, so probably there isn't a dedicated error message for it or you're hitting a bug in the compiler (hence the unknown error message).
Re: DConf '22: No-Allocated 0-terminated path strings
On Friday, 21 October 2022 at 14:34:47 UTC, ag0aep6g wrote: Nitpick: You cannot iterate a true input range twice. You need a forward range for that. Nitpick²: you don't actually need to iterate the range twice ```d //version=AllowMalloc; auto toCStringThen(alias dg, Range)(Range src) /*nothrow*/ if (isInputRange!Range && !isInfinite!Range) { char[10] small = void; size_t i = 0; while(!src.empty && i < small.length) { small[i++] = src.front; src.popFront; } if(i == small.length) { version(AllowMalloc) { import std.container.array; Array!char large = small[]; large ~= src; large ~= '\0'; return dg(large.data); } else { throw new Exception( "C string buffer overflow (%s >= %s)" .format(i+src.walkLength, small.length-1) ); } } else { small[i] = '\0'; return dg(small[0..i]); } } ``` Unfortunately this version does multiple allocations if contents of the range do not fit into the small buffer, but you could avoid that by detecting if `src` is a forward range/defines `.length` and doing `large.reserve` or something similar.
Re: Does D actually support flexible array members?
No, D does not support flexible array members or dynamically sized structs. `char[]` is a D slice, which is NOT equivalent to a C array. A slice is basically a pointer+length pair: ```d // you can't actually name a struct `char[]`, it's just for explanation purposes struct char[] { char* ptr; //pointer to first element size_t length; } ``` Also the allocation code probably only worked by accident and will likely cause memory corruption: ```d void* result = cast(void*)( + ar.currInd); ``` `` doesn't give you a pointer to the first slice element - it gives you a pointer to the slice itself (the `char[]` "struct"). To get a pointer to the first element you can use `ar.currChunk.memory.ptr`, although since the end goal is to get a pointer to the `ar.currInd` element it's preferable to replace the entire line with this: ```d void* result = [ar.currInd]; ``` (this way you get bounds checking on slice indexing so you can't get a pointer past the last element of the slice). Also `void[]` is a more appropriate type for a raw memory array than `char[]` (`char[]` in D is used almost exclusively as "mutable string", and depending on the implementation the garbage collector may not scan `char[]` elements for pointers).
Re: Execute the Shell command and continue executing the algorithm
On Monday, 30 May 2022 at 11:18:42 UTC, Alexander Zhirov wrote: I want to run a command in the background during the execution of the algorithm, and without waiting for its actual execution, because it is "infinite", while continuing the execution of the algorithm and then, knowing the ID of the previously launched command, kill the process. So far I have done so: ```d // Here a long program is launched, as an example `sleep` executeShell("(sleep 1 && echo \"SLEEP\" >> log) &"); while (!interrupted) { // some algorithm is executed here, for example `echo` executeShell("(echo \"OK\" >> log) &"); if (here is my condition termination of the program) { // Here is the termination of the running program } Thread.sleep(1.seconds); } ``` How to organize such an algorithm correctly? You could use [`spawnShell`](https://dlang.org/phobos/std_process.html#spawnShell) instead of `executeShell` to spawn the long-running process. `spawnShell` will return the PID of the spawned process, which you can later use to kill it with the `kill` function. ```d import core.stdc.signal : SIGINT; import std.process; /* note: with spawnShell you don't need & at the end of command, because spawnShell doesn't wait for spawned process to complete */ Pid pid = spawnShell("(sleep 1 && echo \"SLEEP\" >> log)"); while (!interrupted) { // some algorithm is executed here, for example `echo` executeShell("(echo \"OK\" >> log) &"); if (here is my condition termination of the program) { /* Kill the previously spawned process using SIGINT signal */ kill(pid, SIGINT); /* Wait for the killed process to shutdown */ wait(pid); } Thread.sleep(1.seconds); } ```