Proper way to protect (lock) a struct field after initialization ??
Hello All. Is there a standard way to protect a field of a struct after the struct has been initialized? Is this possible with a struct? If not, I suppose a class (object) would be needed? If so, are there any simple pointers to an example of this? Thanks in advance, James
Re: Proper way to protect (lock) a struct field after initialization ??
On Sunday, 8 August 2021 at 10:11:37 UTC, james.p.leblanc wrote: Hello All. Is there a standard way to protect a field of a struct after the struct has been initialized? Is this possible with a struct? If not, I suppose a class (object) would be needed? If so, are there any simple pointers to an example of this? Thanks in advance, James `private` works for structs the same as it does for classes. https://dlang.org/spec/attribute.html#visibility_attributes Perhaps you tried it, realized you could still access it within the same module, and concluded that it didn't work? Consider note #2 at that link: "Symbols with private visibility can only be accessed from within the same module." Import the struct into another module and test the visibility there and you'll get the behavior you're looking for.
Re: Proper way to protect (lock) a struct field after initialization ??
On Sunday, 8 August 2021 at 10:19:46 UTC, jfondren wrote: On Sunday, 8 August 2021 at 10:11:37 UTC, james.p.leblanc wrote: Hello All. Is there a standard way to protect a field of a struct after the struct has been initialized? Is this possible with a struct? If not, I suppose a class (object) would be needed? If so, are there any simple pointers to an example of this? Thanks in advance, James `private` works for structs the same as it does for classes. https://dlang.org/spec/attribute.html#visibility_attributes Perhaps you tried it, realized you could still access it within the same module, and concluded that it didn't work? Consider note #2 at that link: "Symbols with private visibility can only be accessed from within the same module." Import the struct into another module and test the visibility there and you'll get the behavior you're looking for. Hej JFondren, Wow, thanks for the quick response. I had read that about the modules ... but as my test example had failed, I thought that I had misunderstood the larger picture. Based on you kind reply, I went back over my example and found that I had been deceiving myself. With a quick fix-up edit, it indeed is working as your explanation. Now, I proceed onto the trickier part of my endeavor ... Thanks again, and Best Regards, James (Sorry for the noise...)
Re: Proper way to protect (lock) a struct field after initialization ??
On 8/8/21 3:11 AM, james.p.leblanc wrote: Hello All. Is there a standard way to protect a field of a struct after the struct has been initialized? Is this possible with a struct? If not, I suppose a class (object) would be needed? If so, are there any simple pointers to an example of this? Thanks in advance, James I understand your question differently from jfondren. You may be looking for a 'const' (or 'immutable') member: struct S { const int i; this(int i) { // This will work because "first assignment is initialization" this.i = i; } } void main() { auto s = S(42); // This won't work s.i = 43; // This won't work either s = S(44); } Ali
Re: Proper way to protect (lock) a struct field after initialization ??
On Sunday, 8 August 2021 at 10:40:51 UTC, Ali Çehreli wrote: I understand your question differently from jfondren. You may be looking for a 'const' (or 'immutable') member: struct S { const int i; this(int i) { // This will work because "first assignment is initialization" this.i = i; } } void main() { auto s = S(42); // This won't work s.i = 43; // This won't work either s = S(44); } Ali Hello Again Ali, Excellent! I had tried (an erroneous) variant of this idea earlier ... but also failed with my attempt. I am appreciating very much the example you have provided. I will try this approach as well for the problem I am working on. (Some details on my path forward remain unclear ...) Best Regards, James
using "invariant" with structs ... possible to call when a field value is set??
Hello, With structs, I understand that "invariant checking" is called (from dlang tour): It's called after the constructor has run and before the destructor is called. It's called before entering a member function invariant() is called after exiting a member function. But, is is possible to have the invariant checking be performed whenever a field is directly set? For example, suppose a struct "S", has a field "x". I would like to have invariance check in cases such as: S.x = 4; Maybe there is a hidden set field function that gets called that might be exploitable?? Thoughts on this? Possible? Better paths that I should consider? Best Regards, James
Re: using "invariant" with structs ... possible to call when a field value is set??
On Sunday, 8 August 2021 at 11:30:41 UTC, james.p.leblanc wrote: Hello, With structs, I understand that "invariant checking" is called (from dlang tour): It's called after the constructor has run and before the destructor is called. It's called before entering a member function invariant() is called after exiting a member function. But, is is possible to have the invariant checking be performed whenever a field is directly set? For example, suppose a struct "S", has a field "x". I would like to have invariance check in cases such as: S.x = 4; Maybe there is a hidden set field function that gets called that might be exploitable?? Thoughts on this? Possible? Better paths that I should consider? Best Regards, James You can make a field set function like so: ``` struct S { private int x_; int x(int value) { return this.x_ = value; } int x() { return this.x_; } } ``` This will then run invariants. (boilerplate can automate that for you. https://code.dlang.org/packages/boilerplate cough self-advertisement cough)
Debugging linker errors
Hi, I tried to update my server from dmd v2.096.1 to v2.097 and I started getting this linker error: ``` Linking... /usr/bin/ld: .dub/build/executable-ssl11-debug-linux.posix-x86_64-dmd_v2.097.2-beta.1-7651E13F70724FF6B1F8D8B61B1AEABD/gis-collective-api.o: in function `_D3std6traits__T6fqnSymS5crateZ11adjustIdentFAyaZQe': /usr/include/dmd/phobos/std/traits.d:737: undefined reference to `_D3std9algorithm9searching__T8skipOverZ__TQnTAyaTQeZQxFNaNfKQpQrZb' /usr/bin/ld: /usr/include/dmd/phobos/std/traits.d:737: undefined reference to `_D3std9algorithm9searching__T8skipOverZ__TQnTAyaTQeZQxFNaNfKQpQrZb' collect2: error: ld returned 1 exit status Error: linker exited with status 1 /usr/bin/dmd failed with exit code 1. ``` What's the best aproach on debugging linker errors with DMD on linux? Best, Bogdan
Re: using "invariant" with structs ... possible to call when a field value is set??
On Sunday, 8 August 2021 at 11:36:51 UTC, FeepingCreature wrote: You can make a field set function like so: ``` struct S { private int x_; int x(int value) { return this.x_ = value; } int x() { return this.x_; } } ``` This will then run invariants. (boilerplate can automate that for you. https://code.dlang.org/packages/boilerplate cough self-advertisement cough) FC, Thanks! This is exactly what I had hoped might be possible! I had made some naive "newbie-D" attempts at something like this be couldn't get anything to work. Thanks for providing an exable of the exact code that would work. Much obliged! Best Regards, James PS Even more important than solving my immediate problem, I have gained a better understanding of the struct and its member functions.
Re: Debugging linker errors
On Sunday, 8 August 2021 at 11:58:42 UTC, Bogdan wrote: Hi, I tried to update my server from dmd v2.096.1 to v2.097 and I started getting this linker error: ``` Linking... /usr/bin/ld: .dub/build/executable-ssl11-debug-linux.posix-x86_64-dmd_v2.097.2-beta.1-7651E13F70724FF6B1F8D8B61B1AEABD/gis-collective-api.o: in function `_D3std6traits__T6fqnSymS5crateZ11adjustIdentFAyaZQe': /usr/include/dmd/phobos/std/traits.d:737: undefined reference to `_D3std9algorithm9searching__T8skipOverZ__TQnTAyaTQeZQxFNaNfKQpQrZb' /usr/bin/ld: /usr/include/dmd/phobos/std/traits.d:737: undefined reference to `_D3std9algorithm9searching__T8skipOverZ__TQnTAyaTQeZQxFNaNfKQpQrZb' collect2: error: ld returned 1 exit status Error: linker exited with status 1 /usr/bin/dmd failed with exit code 1. ``` What's the best aproach on debugging linker errors with DMD on linux? Best, Bogdan I'd try the following options - `--force` dub to rebuild everything. - `-allinst` in the dflags. - `-verbose` output can show interesting details sometimes. - the different linking mode proposed by dub. if one of te following fixes the issue then maybe that digger can help to detect a regression.
Re: Tracy
On Sunday, 8 August 2021 at 01:37:42 UTC, SealabJaster wrote: Could this be fixed? Or is this intentional? Of course it *could*, anyone can go to [the dlang wiki](https://wiki.dlang.org/LDC) and add a page for it. Johan Engelen is still working on [improving the feature](https://github.com/ldc-developers/ldc/pull/3797), maybe he is intentionally waiting for the feature to reach maturity before putting it on the wiki or [his blog](https://johanengelen.github.io/), but I can't say.
Re: Build time
On Friday, 23 July 2021 at 18:53:06 UTC, JG wrote: Any suggestion on how to try and improve the build time. You could try some of the tools listed on the wiki for build time profiling: https://wiki.dlang.org/Development_tools#Build_time_profiling (intentional bump to aid search results, as apparently this list is not very well known)
Re: How to profile compile times of a source code?
On Saturday, 30 January 2021 at 22:47:39 UTC, Ahmet Sait wrote: I'm looking for ways to figure out what parts of the code slows down the compiler other than brute force trial. You could try some of the tools listed on the wiki for build time profiling: https://wiki.dlang.org/Development_tools#Build_time_profiling (intentional bump to aid search results, as apparently this list is not very well known)
input range with non copyable element
Hello, is there reason why elements of input range must be copyable? For example this example works and copy ctor is never called: ```d import std.algorithm : map; import std.range; struct Foo{ int i; this(scope ref typeof(this) rhs)pure nothrow @safe @nogc{ //this.i = rhs.i; assert(0, "no copy"); } @disable this(scope const ref typeof(this) rhs)pure nothrow @safe @nogc; } void main(){ Foo[] foos = [Foo(1), Foo(2), Foo(3)]; //this work (copy ctor is never called): { auto tmp = foos .map!((ref foo) => foo.i) .array; } } ``` This doesn't work: ```d void main(){ const(Foo)[] foos = [Foo(1), Foo(2), Foo(3)]; //error: { auto tmp = foos .map!((ref foo) => foo.i) .array; } } ``` Source of my problem is in `isInputRange`: ```d import std.range; import std.traits : ReturnType; alias R = const(Foo)[]; //enum bool isInputRange(R) = static assert(is(typeof(R.init) == R)); ///OK static assert(is(ReturnType!((R r) => r.empty) == bool)); ///OK static assert(is(typeof((return ref R r) => r.front)));///ERROR, copy result of front static assert(!is(ReturnType!((R r) => r.front) == void)); ///OK static assert(is(typeof((R r) => r.popFront))); ///OK ``` Is it possible to make lambda return `auto ref`?
How to divide by space keeping words with spaces inside quotes?
How to divide by space keeping words with spaces inside quotes? Exanple: string text = "Duck Cat \"Carl Rivers\" Dog"; I want split to: ["Duck", "Cat", "Carl Rivers", "Dog"] ATENTION: I DON'T WANT: ["Duck", "Cat", "Carl", "Rivers", "Dog"] How can I get it in Dlang?
Re: How to divide by space keeping words with spaces inside quotes?
On Sunday, 8 August 2021 at 23:04:32 UTC, Marcone wrote: How to divide by space keeping words with spaces inside quotes? Well the designers of ASCII were morons who decided that open quote and close quote would be the same damn letter, so it's a little trickier. Basically what you have to do is process it character by character into a finite state machine that switches between word mode, space mode, and quoting mode, accounting for backslash escapes since morons, etc. so you kinda need them. I dunno any modules in specific that do it, but something like: ```d string somestr = "Duck Cat \"Carl Rivers\" Dog"; enum FSM { QUOTING, WORD, SPACE }; struct FSM { FSM mode; bool backslash; Appender!char cur; Appender!string accum; } FSM fsm; fsm.mode = SPACE; foreach(char ch: somestr) { if(fsm.backslash) { fsm.backslash = false; cur.add(ch); continue; } switch(fsm.mode) { case FSM.QUOTING: switch(ch) { case '\\': cur.add('\\'); fsm.backslash = true; case '"': fsm.mode = FSM.SPACE; accum.add(tostring(cur.data)); cur = appender!char; break; default: cur.add(ch); }; break; case FSM.WORD: switch(ch) { case '\\': cur.add('\\'); fsm.backslash = true; case ' ': case '\t': fsm.mode = FSM.SPACE; if(cur.data.length) { accum.add(tostring(cur.data)); cur = appender!char; } break; default: cur.add(ch); }; break; case FSM.SPACE: switch(ch) { case '\\': fsm.backslash = true; fsm.mode = WORD; cur.add('\\'); break; case ' ': case '\t': case '\n': break; case '"': fsm.mode = FSM.QUOTING; break; default: cur.add(ch); fsm.mode = FSM.WORD; break; }; }; } string[] result = fsm.data; print(result); ``` (untested pseudocode that won't work btw)
Re: input range with non copyable element
On Sunday, 8 August 2021 at 18:36:02 UTC, vit wrote: Hello, is there reason why elements of input range must be copyable? By design, not that I can think of. But it is assumed all over the place, unfortunately. You can make your `front` method return by `ref`, but you're still going to get bitten as soon as you do any `std.algorithm`-based operation, as storage classes are not inferred (https://issues.dlang.org/show_bug.cgi?id=9423) and things get passed by value to your delegates by default. The problem can also show up when you `foreach` over a range (https://issues.dlang.org/show_bug.cgi?id=15413). And finally, `std.algorithm` need to support it. So currently you'll have to jump through a lot of hops to get it to work. It'll be much easier to use your own `map` & co to get the job done for the time being. Hopefully at some point in the near future that won't be needed anymore.
Re: How to divide by space keeping words with spaces inside quotes?
On Sunday, 8 August 2021 at 23:04:32 UTC, Marcone wrote: How to divide by space keeping words with spaces inside quotes? Exanple: string text = "Duck Cat \"Carl Rivers\" Dog"; I want split to: ["Duck", "Cat", "Carl Rivers", "Dog"] ATENTION: I DON'T WANT: ["Duck", "Cat", "Carl", "Rivers", "Dog"] How can I get it in Dlang? You can use a regex. Apparently [the pattern](https://regex101.com/r/cyx0pC/1) `(\"[\w ]*\")|\w*` would work, other option is to write a dedicated lexer, as suggested in the other answer.
Re: How to divide by space keeping words with spaces inside quotes?
On Monday, 9 August 2021 at 04:19:05 UTC, Basile.B wrote: On Sunday, 8 August 2021 at 23:04:32 UTC, Marcone wrote: How to divide by space keeping words with spaces inside quotes? Exanple: string text = "Duck Cat \"Carl Rivers\" Dog"; I want split to: ["Duck", "Cat", "Carl Rivers", "Dog"] ATENTION: I DON'T WANT: ["Duck", "Cat", "Carl", "Rivers", "Dog"] How can I get it in Dlang? You can use a regex. Apparently [the pattern](https://regex101.com/r/cyx0pC/1) `(\"[\w ]*\")|\w*` would work with `+` as quantifier actually `(\"[\w ]+\")|\w+`
Re: How to divide by space keeping words with spaces inside quotes?
On Sunday, 8 August 2021 at 23:04:32 UTC, Marcone wrote: How to divide by space keeping words with spaces inside quotes? Exanple: string text = "Duck Cat \"Carl Rivers\" Dog"; I want split to: ["Duck", "Cat", "Carl Rivers", "Dog"] ATENTION: I DON'T WANT: ["Duck", "Cat", "Carl", "Rivers", "Dog"] How can I get it in Dlang? regex: ```d // test with: dmd -unittest -main -run filename.d string[] splitquote(string s) { import std.regex : matchAll, regex; import std.array : array; import std.algorithm : map; return s.matchAll(regex(`"([\w ]+)"|(\w+)`)).map!"a[2] ? a[2] : a[1]".array; } unittest { assert(`Duck Cat Carl`.splitquote == ["Duck", "Cat", "Carl"]); assert(`Duck "Cat" Carl`.splitquote == ["Duck", "Cat", "Carl"]); assert(`Duck "Cat Carl"`.splitquote == ["Duck", "Cat Carl"]); assert(`"Duck" "Cat Carl`.splitquote == ["Duck", "Cat", "Carl"]); // GIGO assert(`"Duck Cat" "Carl"`.splitquote == ["Duck Cat", "Carl"]); } ``` PEG: ```d /++ dub.sdl: dependency "pegged" version="~>0.4.5" +/ // test with: dub run -bunittest --single filename.d import pegged.grammar; mixin(grammar(q"PEG Quotable: Words< (' '* (Quoted/Unquoted))* Quoted <~ :doublequote (!doublequote .)+ :doublequote Unquoted < identifier+ PEG")); string[] splitquote(string s) { return Quotable(s).matches; } unittest { assert(`Duck Cat Carl`.splitquote == ["Duck", "Cat", "Carl"]); assert(`Duck "Cat" Carl`.splitquote == ["Duck", "Cat", "Carl"]); assert(`Duck "Cat Carl"`.splitquote == ["Duck", "Cat Carl"]); assert(`"Duck" "Cat Carl`.splitquote == ["Duck"]); assert(`"Duck Cat" "Carl"`.splitquote == ["Duck Cat", "Carl"]); } void main() { } ```