Re: UTF-16 endianess
On Fri, 29 Jan 2016 18:58:17 -0500, Steven Schveighoffer wrote: >>> Note the version identifiers BigEndian and LittleEndian can be used to >>> compile the correct code. >> >> This solution is of no use to me as I don't want to change the endianess in >> general. > > What I mean is that you can annotate your code with version statements like: > > version(LittleEndian) > { > // perform the byteswap > ... > } > > so your code is portable to BigEndian systems (where you would not want > to byte swap). That's a good point, thanks. -- Marek Janukowicz
Re: UTF-16 endianess
On Fri, 29 Jan 2016 17:43:26 -0500, Steven Schveighoffer wrote: >> Is there anything I should know about UTF endianess? > > It's not any different from other endianness. > > In other words, a UTF16 code unit is expected to be in the endianness of > the platform you are running on. > > If you are on x86 or x86_64 (very likely), then it should be little endian. > > If your source of data is big-endian (or opposite from your native > endianness), To be precise - my case is IMAP UTF7 folder name encoding and I finally found out it's indeed big endian, which explains my problem (as I'm indeed on x86_64). > it will have to be converted before treating as a wchar[]. Is there any clever way to do the conversion? Or do I need to swap the bytes manually? > Note the version identifiers BigEndian and LittleEndian can be used to > compile the correct code. This solution is of no use to me as I don't want to change the endianess in general. -- Marek Janukowicz
UTF-16 endianess
I have trouble understanding how endianess works for UTF-16. For example UTF-16 code for 'ł' character is 0x0142. But this program shows otherwise: import std.stdio; public void main () { ubyte[] properOrder = [0x01, 0x42]; ubyte[] reverseOrder = [0x42, 0x01]; writefln( "proper: %s, reverse: %s", cast(wchar[])properOrder, cast(wchar[])reverseOrder ); } output: proper: 䈁, reverse: ł Is there anything I should know about UTF endianess? -- Marek Janukowicz
Re: multiline string literal with CRLF
anonymous wrote: >> Is there any way to input such a literal? Both `...` and q"EOS...EOS" do >> not allow escape sequences. I'm on Linux, but I need precisely CRLF, not >> just \n. > > I'm probably missing the point, but: > > "Hello\r\nworld" > > Or if you want to include the \n verbatim: > > "Hello\r > world" Thanks, this works - I don't know how I did it the first time, because I definitely tried that and failed. The other solution by Adam also works - thanks. -- Marek Janukowicz
multiline string literal with CRLF
Is there any way to input such a literal? Both `...` and q"EOS...EOS" do not allow escape sequences. I'm on Linux, but I need precisely CRLF, not just \n. -- Marek Janukowicz
std.concurrency.send problems with immutable
This program works fine: import std.concurrency; struct A { string a,b; } void main () { immutable A a = immutable A( "blah" ); send( thisTid, a ); } But if change struct A declaration to: struct A { string a,b,c; } I get this error during compilation: /opt/dmd2/linux/bin64/../../src/phobos/std/variant.d(653): Error: cannot modify immutable expression *p /opt/dmd2/linux/bin64/../../src/phobos/std/variant.d(580): Error: template instance std.variant.VariantN!32LU.VariantN.opAssign!(immutable(A)) error instantiating /opt/dmd2/linux/bin64/../../src/phobos/std/concurrency.d(117): instantiated from here: __ctor!(immutable(A)) /opt/dmd2/linux/bin64/../../src/phobos/std/concurrency.d(628): instantiated from here: __ctor!(immutable(A)) /opt/dmd2/linux/bin64/../../src/phobos/std/concurrency.d(618): instantiated from here: _send!(immutable(A)) /opt/dmd2/linux/bin64/../../src/phobos/std/concurrency.d(594): instantiated from here: _send!(immutable(A)) Is this is a bug? On a related note - sometimes when sending a shared struct I get a compilation error similar to this: /opt/dmd2/linux/bin64/../../src/phobos/std/variant.d(638): Error: function core.stdc.string.memcpy (void* s1, const(void*) s2, ulong n) is not callable using argument types (ubyte[32]*, shared(Notification)*, ulong) /opt/dmd2/linux/bin64/../../src/phobos/std/variant.d(580): Error: template instance std.variant.VariantN!32LU.VariantN.opAssign!(shared(Notification)) error instantiating /opt/dmd2/linux/bin64/../../src/phobos/std/concurrency.d(117): instantiated from here: __ctor!(shared(Notification)) /opt/dmd2/linux/bin64/../../src/phobos/std/concurrency.d(628): instantiated from here: __ctor!(shared(Notification)) /opt/dmd2/linux/bin64/../../src/phobos/std/concurrency.d(618): instantiated from here: _send!(shared(Notification)) /opt/dmd2/linux/bin64/../../src/phobos/std/concurrency.d(594): instantiated from here: _send!(shared(Notification)) If I then add more fields to the struct (eg. dummy "string a,b") it compiles fine. Is this another bug or am I missing something? -- Marek Janukowicz
Syntax: how to return shared?
How do I mark a function as returning shared object? This won't compile: shared Foo foo () { ... } This does, but looks somewhat awkward to me: shared (shared Foo) foo () { ... } -- Marek Janukowicz
Subclasses in std.concurrency.receive pattern match
Hi Coming back after a (too long) break from D programming. Using DMD 2.067.1: # cat receive_subclass.d import std.stdio; import std.concurrency; class A {} class B : A {} void worker () { while (true) { receive( (shared B b) { writefln( "Got B: %s", cast(B)b ); }, (shared A a) { writefln( "Got A: %s", cast(A)a ); } ); } } void main () { shared A arg = new B; Tid tid = spawn(&worker); send( tid, arg); send( tid, cast(shared B)arg); receive( (bool) {} ); // wait } # dmd -run receive_subclass.d Got A: receive_subclass.B // XXX: we got B, but it was matched as A Got B: receive_subclass.B So patten matching only works on type of containing variable, not the type of the object itself. Is it possible to work around this? I need to receive objects from rather large subclass hierarchy and it would be much more convenient for me to recognize particular subclass using receive than some type of multiple "cast & check" clauses. On a related matter - how does GC behave on such class objects (created in one thread, casted to shared and handled by another thread)? Won't the object get possibly GC'ed when it runs out of scope in origin thread while handler thread still uses it? -- Marek Janukowicz
Re: Console widget library
Adam D. Ruppe wrote: >> Is there any console widget library available for D? > > something like this? > https://github.com/klamonte/d-tui > > I believe it works on both windows and linux now. I've never > actually used it for a real application, but when the author > linked me to it I played briefly and thought it was pretty boss. Wow, that was quick :) D-tui looks like something worth taking a look - thanks. -- Marek Janukowicz
Console widget library
Is there any console widget library available for D? I mean something like high level library on top of ncurses. Maybe anyone took a shot at libyui wrapper? -- Marek Janukowicz
Re: Compile time data structure
Ali Çehreli wrote: > On 09/16/2013 01:24 PM, Marek Janukowicz wrote: > > >static string[string] columns () { > // ... > >} > > Although the function itself is static, it returns a dynamic value. > > > foreach( attr, col; columns() ) { > >__traits(getMember, me, attr) = typeof(__traits(getMember, me, > > attr)).init; > > } > > That foreach is a run-time foreach because columns()'s return value is a > run-time value. > > As far as I know, static foreach is only for tuples (or TypeTuples). If > you can generate the AA as a tuple, then the foreach will be evaluated > at compile time. I read your articles about tuples and templates and it all now makes more sense (why is your book not linked on dlang.org? It is much better stuff for beginners than official D docs). However, there is still one thing I struggle with: how do I create a tuple at compile time if I'm getting information I want to put into it in a foreach? All the examples I found create a tuple with all it's attributes available, while I get mine in an iterative manner... -- Marek Janukowicz
Re: Mixin namespace ambiguity?
Kenji Hara wrote: > Currently this is not a bug. > > Looking from the module 'main', the mixin identifier 'X' declared > in main.d is *closer* than the 'X' declared in aux.d, because the > latter exists beyond the module import boundary. > Therefore, the use of 'X' in main.d would prefere the `mixin > A!("a in main") X`. I get this one - if X was eg. a class and I was calling it's static member it would work the same way. > On the other hand, when the name search, all mixed-in symbols are > treated as if they are just imported at the mixed-in scope. Could you please elaborate a bit more or point me to some documentation where this is described? If the mixins are imported at mixed-in scope, my understanding would be the one in 'main' is closer than the one in 'aux'. > Therefore, even from main.d, the two mixed-in functions 'a' have > same closeness, and the call is ambiguous because they have > exactly same signature. -- Marek Janukowicz
Re: Compile time data structure
Ali Çehreli wrote: > Could you please provide complete code. Sure. This is of course stripped down just for demonstration purposes: struct Attr { string name; } mixin template Model() { static string[string] columns () { string[string] cols; alias type = typeof(this); // Basically - get all members with @Attr UDA and build AA out of those foreach( field; __traits(derivedMembers, type)) { static if( is(typeof(__traits(getAttributes, __traits(getMember, type, field))) blah)) { foreach( uda; __traits(getAttributes, __traits(getMember, type, field))) { static if (is (typeof(uda) == Attr)) { static if (uda.name == "") cols[field] = field; else cols[field] = uda.name; } } } } return cols; } alias typeof(this) Me; static Me initialize () { Me me = new Me(); foreach( attr, col; columns() ) { __traits(getMember, me, attr) = typeof(__traits(getMember, me, attr)).init; } return me; } } class ExampleModel { @Attr() int id; @Attr( "field_id" ) int fieldId; mixin Model; } void main () { ExampleModel ex = ExampleModel.initialize(); } -- Marek Janukowicz
Compile time data structure
I need to gather some data in compile time basing on UDA. struct Attr { string name; } mixin template Model() { static string[string] columns () { string[string] cols; alias type = typeof(this); // Basically - get all members with @Attr UDA and build AA out of those foreach( field; __traits(derivedMembers, type)) { static if( is(typeof(__traits(getAttributes, __traits(getMember, type, field))) blah)) { foreach( uda; __traits(getAttributes, __traits(getMember, type, field))) { static if (is (typeof(uda) == Attr)) { static if (uda.name == "") cols[field] = field; else cols[field] = uda.name; } } } } return cols; } } class ExampleModel { @Attr() int id; @Attr( "field_id" ) int fieldId; mixin Model; } This works and the result of columns() method is as expected. However, if I try to use it in another compile time fuction, eg: foreach( attr, col; columns ) { __traits(getMember, obj, attr) = 1; } it fails saying "attr" cannot be read at compile time. I suspect I can't just build AA during compile time, but is there any other way for columns() method to return a structure that could be further evaluated at compile time? -- Marek Janukowicz
Mixin namespace ambiguity?
The code to reproduce the problem consists of 3 modules: mix.d: module mix; mixin template A( alias x) { string a () { return x; } } aux.d: module aux; import mix; mixin A!("a in aux") X; string b () { return "b in aux"; } main.d: module main; import aux; import mix; import std.stdio; mixin A!("a in main") X; string b () { return "b in main"; } void main () { writefln( "a: %s", X.a ); // Line 1 //writefln( "a: %s", a ); // Line 2 writefln( "b: %s", b ); // Line 3 } I run it with: dmd -run main.d aux.d mix.d Line 1 works. Line 3 works. Line 2 fails with: main.d(13): Error: main.A!("a in main").a at mix.d(5) conflicts with aux.A! ("a in aux").a at mix.d(5) If I omit mixin identifier ("X"), there is no way I can make the call to "a" work without prepending module name. My question is: why calling a function with the same name (from different modules) works when: - it is just a regular function - it is a mixed-in function with mixin identifier (even though the identifier is ambiguous) and it doesn't when it's a mixed-in function with no mixin identifier. My first impression is that either both line 1 and 2 should work or neither of them should work. It's no surprise to me that line 3 works (and it matches the documentation), so I basically included that just for reference. -- Marek Janukowicz
Re: dmd memory usage/static lib/algorithm bug?
H. S. Teoh wrote: > On Thu, Aug 29, 2013 at 12:45:05AM +0200, Marek Janukowicz wrote: >> H. S. Teoh wrote: > [...] >> > Oh, and BTW, are you on Linux 32-bit or 64-bit? Don't know if that >> > makes a difference, but just in case. >> >> 64-bit > [...] > > Maybe try compiling with -m32 and see if it makes a difference? If so, > it may be a 64-bit related dmd bug. I'm also having trouble building a > working compiler toolchain with a purely 64-bit environment. Yeah, it makes a difference :) ./main(_D4core7runtime18runModuleUnitTestsUZb19unittestSegvHandlerUiPS4core3sys5posix6signal9siginfo_tPvZv+0x2c) [0x80a8c64] linux-gate.so.1(__kernel_rt_sigreturn+0x0)[0xe410] ./main(_D6sorter14__unittestL9_3FZv101__T13quickSortImplS65_D6sorter14__unittestL9_3FZv2dgPFNaNbNfS6sorter3ValS6sorter3ValZbTAS6sorter3ValZ13quickSortImplMFAS6sorter3ValZv+0x1a7) [0x80a1b53] ./main(_D6sorter14__unittestL9_3FZv122__T4sortS65_D6sorter14__unittestL9_3FZv2dgPFNaNbNfS6sorter3ValS6sorter3ValZbVE3std9algorithm12SwapStrategy0TAS6sorter3ValZ4sortMFAS6sorter3ValZS6sorter14__unittestL9_3FZv99__T11SortedRangeTAS6sorter3ValS65_D6sorter14__unittestL9_3FZv2dgPFNaNbNfS6sorter3ValS6sorter3ValZbZ11SortedRange+0x17) [0x80a20cb] ./main(_D6sorter14__unittestL9_3FZv+0x6d)[0x80a2079] ./main(_D6sorter9__modtestFZv+0x8)[0x80a21ac] ./main(_D4core7runtime18runModuleUnitTestsUZb16__foreachbody352MFKPS6object10ModuleInfoZi+0x24) [0x80a8ccc] ./main(_D2rt5minfo17moduleinfos_applyFMDFKPS6object10ModuleInfoZiZi16__foreachbody541MFKS2rt14sections_linux3DSOZi+0x37) [0x80a5f47] ./main(_D2rt14sections_linux3DSO7opApplyFMDFKS2rt14sections_linux3DSOZiZi+0x2c) [0x80a619c] ./main(_D2rt5minfo17moduleinfos_applyFMDFKPS6object10ModuleInfoZiZi+0x14) [0x80a5ef4] ./main(runModuleUnitTests+0x87)[0x80a8bd7] ./main(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZi6runAllMFZv+0x25)[0x80a4a55] ./main(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZi7tryExecMFMDFZvZv+0x18) [0x80a46c0] ./main(_d_run_main+0x121)[0x80a4691] ./main(main+0x14)[0x80a4564] /lib32/libc.so.6(__libc_start_main+0xf3)[0xf74d4943] Segmentation fault (core dumped) This stacktrace did not show in 64-bit version, but the problem persists. -- Marek Janukowicz
Re: dmd memory usage/static lib/algorithm bug?
H. S. Teoh wrote: > On Wed, Aug 28, 2013 at 11:02:17PM +0200, Marek Janukowicz wrote: >> I was finally able to create simple test case that probably reproduces >> the bug (probably, because the stack trace is completely different, >> but the code that is there is similar). This requires 2 source code >> files: > [...] >> Run with: >> >> dmd -unittest main.d sorter.d && ./main >> >> For me this results in a segfault. Changing one of many seemingly >> unrelated details (eg. moving offending code directly to main, >> commenting out std.stdio import in main.d) makes the problem >> disappear. >> >> Can anyone try to reproduce that? Again, I'm on DMD 2.063.2. > > It doesn't seem to happen on git HEAD. I'm going to try 2.063.2 and see > what happens. > > Oh, and BTW, are you on Linux 32-bit or 64-bit? Don't know if that makes > a difference, but just in case. 64-bit -- Marek Janukowicz
Re: dmd memory usage/static lib/algorithm bug?
I was finally able to create simple test case that probably reproduces the bug (probably, because the stack trace is completely different, but the code that is there is similar). This requires 2 source code files: main.d: module main; // This line must be there - import any module from std causes is necessary to // reproduce the bug import std.stdio; import sorter; void main () { } --- sorter.d: module sorter; import std.algorithm; struct Val { int i; } unittest { Val [] arr; arr ~= Val( 2 ); arr ~= Val( 1 ); // This works arr.sort!((Val a, Val b) { return a.i < b.i; }); // This segfaults when sorting auto dg = (Val a, Val b) { return a.i < b.i; }; arr.sort!(dg); } -- Run with: dmd -unittest main.d sorter.d && ./main For me this results in a segfault. Changing one of many seemingly unrelated details (eg. moving offending code directly to main, commenting out std.stdio import in main.d) makes the problem disappear. Can anyone try to reproduce that? Again, I'm on DMD 2.063.2. H. S. Teoh - thanks for your detailed description, but this test case probably sheds some more light and invalidates some of your hyphotheses. As for building static library - I thought it would be easier, so if the bug remains unresolved I'll probably just rebuild the whole phobos. The problem is definitely not some old version of libphobos2.a stuck around, because the problem could be reproduced exactly the same way on 3 machines I tried. -- Marek Janukowicz
dmd memory usage/static lib/algorithm bug?
This is really a cross-domain issue, but I didn't feel like splitting it into separate posts would make sense. I use DMD 2.063.2 on Linux 64-bit. I have some code in my (non-trivial) application that basically corresponds to this: import std.stdio, std.algorithm, std.array; void main () { struct Val { int i; } Val[] arr; arr ~= Val( 3 ); arr ~= Val( 1 ); arr ~= Val( 2 ); auto sorter = (Val a, Val b) { return a.i < b.i; }; writefln( "sorted: %s", arr.sort!(sorter)); } While this simple example works, I'm getting segfaults with corresponding code in thisi bigger project. Those segfaults can be traced down to algorithm.d line 8315 or another line (8358?) that use this "sorter" lambda I passed to "sort!" - suggesting it is a bad memory reference. I tried to create a simple test case that would fail similarly, but to no avail. I can't make the code for my whole project available, so let's just say it's either some bug in DMD or something caused by my limited knowledge of D. Now the funny things begin: I copied algorithm.d to my project in an attempt to make some modifications to it (hopefully to fix the problem or at least get some insight into its nature), but things miraculously started working! This leads me to the suspicion there is something wrong with libphobos2.a file provided with DMD tarball. Next problem in the line is that compilation of my project with algorithm.d included takes almost 4GB of RAM. While I'm aware of the fact DMD deliberately doesn't free the memory for performance purposes, this makes the compilation fail due to insufficient memory on machines with 4GB RAM (and some taken). So my questions are: - how can I limit DMD memory usage? - how can I include a static library with my project? I can compile algorithm.d to a static lib, but how do I include this one explicitly with my project while the rest of Phobos should be taken from the stock libphobos2.a ? - any other ideas how to solve my problems on any level? -- Marek Janukowicz
Re: A template returning a delegate [was: template returning delegate]
Marek Janukowicz wrote: > Yet another problem I just spotted: > > --- > > import std.stdio, std.string; > > struct Val { > int i; > byte b; > } > > template templ( T ) { > >auto templ (T obj, string name) { > foreach( s; __traits(derivedMembers, T)) { > if (s == name) { > static if( is(typeof(__traits(getAttributes, __traits(getMember, > T, > s))) blah)) { // Rule out "non-regular" members > //return format( "%s", __traits(getMember, obj, s)); // Version > A return cast(string delegate())() { return > format("%s",__traits(getMember, obj, s)); }; // Version B > } > } > } > throw new Exception("Invalid member"); > } > } > > void main (string [] args) { > Val v = Val(1, 2); > //writefln( "%s: %s", args[1], templ!()(v, args[1])); // Version A > writefln( "%s: %s", args[1], templ!()(v, args[1])()); // Version B > } > > --- > > Now running: > $ dmd -run member.d i > /usr/lib/gcc/x86_64-pc-linux-gnu/4.6.3/../../../../x86_64-pc-linux- > gnu/bin/ld: Warning: size of symbol > `_D6member23__T5templTS6member3ValZ5templFNfS6member3ValAyaZDFZAya9__lambda1MFZAya' > changed from 32 in member.o to 33 in member.o > i: 1 > > $ dmd -run member.d b > /usr/lib/gcc/x86_64-pc-linux-gnu/4.6.3/../../../../x86_64-pc-linux- > gnu/bin/ld: Warning: size of symbol > `_D6member23__T5templTS6member3ValZ5templFNfS6member3ValAyaZDFZAya9__lambda1MFZAya' > changed from 32 in member.o to 33 in member.o > b: 1 # Why not 2? > > If I compile using ldc2 I get exactly the same result, so the delegate > returned from template always returns value of "i" member (maybe it's > always the first member that is returned). Ld warning is not present then. > > However if I comment "Version B" lines and uncomment "Version A" (which > means I return the result directly instead of returning the delegate I get > expected results: > > $ dmd -run member.d i > i: 1 > > $ dmd -run member.d b > b: 2 > > Also no ld warning in this case. Figured it out - this code works as expected: import std.stdio, std.string; struct Val { int i; byte b; } template templ( T ) { auto dg(alias s)( T obj ) { return () { return format("%s",__traits(getMember, obj, s)); }; } auto templ (T obj, string name) { foreach( s; __traits(derivedMembers, T)) { if (s == name) { static if( is(typeof(__traits(getAttributes, __traits(getMember, T, s))) blah)) { // Rule out "non-regular" members return dg!(s)(obj); } } } throw new Exception("Invalid member"); } } void main (string [] args) { Val v = Val(1, 2); writefln( "%s: %s", args[1], templ!()(v, args[1])()); } My mistake was to return delegate with __traits directly inside, why the correct way to do this was to create delegate using template. However, now I'm a bit confused my code worked at all instead of failing right away. -- Marek Janukowicz
Re: A template returning a delegate [was: template returning delegate]
After I sent the message I realized my limited English knowledge made me make a subject that actually had quite a different meaning than I intended :) Now it's hopefully fine or at least less ambiguous. -- Marek Janukowicz
template returning delegate
Yet another problem I just spotted: --- import std.stdio, std.string; struct Val { int i; byte b; } template templ( T ) { auto templ (T obj, string name) { foreach( s; __traits(derivedMembers, T)) { if (s == name) { static if( is(typeof(__traits(getAttributes, __traits(getMember, T, s))) blah)) { // Rule out "non-regular" members //return format( "%s", __traits(getMember, obj, s)); // Version A return cast(string delegate())() { return format("%s",__traits(getMember, obj, s)); }; // Version B } } } throw new Exception("Invalid member"); } } void main (string [] args) { Val v = Val(1, 2); //writefln( "%s: %s", args[1], templ!()(v, args[1])); // Version A writefln( "%s: %s", args[1], templ!()(v, args[1])()); // Version B } --- Now running: $ dmd -run member.d i /usr/lib/gcc/x86_64-pc-linux-gnu/4.6.3/../../../../x86_64-pc-linux- gnu/bin/ld: Warning: size of symbol `_D6member23__T5templTS6member3ValZ5templFNfS6member3ValAyaZDFZAya9__lambda1MFZAya' changed from 32 in member.o to 33 in member.o i: 1 $ dmd -run member.d b /usr/lib/gcc/x86_64-pc-linux-gnu/4.6.3/../../../../x86_64-pc-linux- gnu/bin/ld: Warning: size of symbol `_D6member23__T5templTS6member3ValZ5templFNfS6member3ValAyaZDFZAya9__lambda1MFZAya' changed from 32 in member.o to 33 in member.o b: 1 # Why not 2? If I compile using ldc2 I get exactly the same result, so the delegate returned from template always returns value of "i" member (maybe it's always the first member that is returned). Ld warning is not present then. However if I comment "Version B" lines and uncomment "Version A" (which means I return the result directly instead of returning the delegate I get expected results: $ dmd -run member.d i i: 1 $ dmd -run member.d b b: 2 Also no ld warning in this case. -- Marek Janukowicz
Getting member by name in runtime
I get a string from HTTP request and I need to process a member of this name of an object. I would like to use __traits(getMember) for that, but of course it doesn't work with runtime parameters. So what I ended up with is: foreach( s; __traits(derivedMembers, typeof(obj))) { if (s == name) ... } Of course this looks suboptimal as I run the loop until I find a member matching the name. Is there any better way to do this? -- Marek Janukowicz
Re: ORM libraries out there
Dicebot wrote: > On Tuesday, 20 August 2013 at 15:47:42 UTC, Marek Janukowicz > wrote: >> Does anyone know about any decent ORM (Object Relational >> Mapping or whatever >> it stands for) libraries for D? If someone actually tried some >> of those it >> would be a big plus. > > http://code.dlang.org/packages/hibernated > > ( have not tried it ;) ) Thanks. Honestly I don't like this one, it seems to inherit Java "oververboseness". 4 lines just to establish a connection - come on! -- Marek Janukowicz
Re: Typeof woes
Andrej Mitrovic wrote: > On 8/21/13, H. S. Teoh wrote: >> and typeof(this.Smth) is invalid because this.Smth is already a >> type, so you can't apply typeof to it. > > I am beginning to wonder if typeof(typeof(expr)) is worthy of an > error. Would we end up having any bugs if we were to allow typeof() to > work on types (IOW it would just alias itself to the type)? It's not always considered an error, this code compiles fine (my guess is the "is" expression does some magic with its arguments): import std.stdio; class A { int a; enum Smth { A }; void list () { foreach( s; __traits(derivedMembers, typeof(this))) { static if (is (typeof(typeof(typeof(__traits(getMember, this, s == int)) { writefln ("%s is int", s ); } } } } void main () { A a = new A(); a.list(); } -- Marek Janukowicz
Re: Typeof woes
H. S. Teoh wrote: > On Wed, Aug 21, 2013 at 01:42:11AM +0200, Marek Janukowicz wrote: >> Given this short program: >> >> class A { >> >> int i; >> //enum Smth { X }; >> >> void list () { >> foreach( s; __traits(derivedMembers, typeof(this))) { >> alias type = typeof(__traits(getMember, this, s)); >> } >> } >> } >> >> void main () { >> A a = new A(); >> a.list(); >> } >> >> if I uncomment "enum" line I get compilation error: >> aa.d(8): Error: argument Smth to typeof is not an expression >> >> So far it only happened with enums for me, but admittedly I didn't >> check all the possible types out there. > > The reason is that derivedMembers returns *all* members, including enum > definitions, not just member variables and methods. So this includes > 'Smth', and typeof(this.Smth) is invalid because this.Smth is already a > type, so you can't apply typeof to it. Yes, I do understand this, however the behavior indicated below (your last question and my code) got me really confused. > > To get around this, you will need to use static if, maybe something like > this: > > void list() { > // Warning: untested code > foreach(s; __traits(derivedMembers, typeof(this))) { > static if (is(typeof(__traits(getMember, this, s)) type)) { > // here, 'type' is bound to the type of > // the member. > } > } > } > > This uses the is(X Y) form, where if X is a valid type, then it gets > aliased to Y inside the static if block. (I have to admit I'm not that > pleased with D's is-expressions due to their confusing syntax, but they > do work and are quite a powerful tool to use once you understand them.) This code works, thank you. However, if I may share my newbie impression - current traits implementation looks not complete to me. What I want to do is to process those members that are of certain type - instead of a nice one- liner to identify those, I already need two and the first (the one you provided above) looks like a hack to me, because I have to check if some expression is valid. The whole issue (which to me looks like a quite standard metaprogramming task) already took me a few hours (and also some time of you and the other helpful guys) and I can't get rid of the impression either the docs are lacking or we could use some more traits. >> What's even more interesting it's just alias problem, the expression >> "typeof(__traits(getMember, this, s))" might be used eg. in static if >> even for enums. >> >> Is this a bug or do I miss something (again)? > [...] > > Are you sure about that? That doesn't sound right to me. Yes, I'm sure, here goes modified code: import std.stdio; class A { int a; enum Smth { A }; void list () { foreach( s; __traits(derivedMembers, typeof(this))) { //alias type = typeof(__traits(getMember, this, s)); static if (is (typeof(__traits(getMember, this, s)) == int)) { writefln ("%s is int", s ); } } } } void main () { A a = new A(); a.list(); } which outputs: a is int -- Marek Janukowicz
Typeof woes
Given this short program: class A { int i; //enum Smth { X }; void list () { foreach( s; __traits(derivedMembers, typeof(this))) { alias type = typeof(__traits(getMember, this, s)); } } } void main () { A a = new A(); a.list(); } if I uncomment "enum" line I get compilation error: aa.d(8): Error: argument Smth to typeof is not an expression So far it only happened with enums for me, but admittedly I didn't check all the possible types out there. What's even more interesting it's just alias problem, the expression "typeof(__traits(getMember, this, s))" might be used eg. in static if even for enums. Is this a bug or do I miss something (again)? -- Marek Janukowicz
Re: Struct - static initialization "on-the-fly"
Ali Çehreli wrote: > On 08/20/2013 03:47 PM, Marek Janukowicz wrote:> In this program: > > > > import std.stdio, std.json; > > > > void main () { > >JSONValue jsonSet; > >jsonSet.type = JSON_TYPE.OBJECT; > >JSONValue a = { type: JSON_TYPE.STRING, str: "abcde" }; // This work > >jsonSet.object["a"] = a; > >jsonSet.object["b"] = { type: JSON_TYPE.STRING, str: "jjf" }; // > THIS LINE > > } > > > > marked line will not compile failing with: > > json.d(8): Error: found ':' when expecting ';' following statement > > > > Is there any way to selectively initialize a struct while using it as > > AA value? The way I set "a" key works, but requires two lines instead > > of one and I have many such elements to set. I can't initialize all > > members of JSONValue, because there are many and I only need those two. > > > > Unfortunately, that syntax works only when initializing a variable. Too bad :( Is there any specific reason for that or is that just not implemented (yet)? > Would you like the following syntax instead? > > root.object["a"] = to!JSONValue("abcde"); > root.object["b"] = to!JSONValue("jjf"); > > If so, the following thread has a rough implementation of a 'to' > specialization for JSONValue: > >http://forum.dlang.org/post/jl6bsn$67k$1...@digitalmars.com Yes, this fulfills my "single line" requirement, thanks! -- Marek Janukowicz
Struct - static initialization "on-the-fly"
In this program: import std.stdio, std.json; void main () { JSONValue jsonSet; jsonSet.type = JSON_TYPE.OBJECT; JSONValue a = { type: JSON_TYPE.STRING, str: "abcde" }; // This work jsonSet.object["a"] = a; jsonSet.object["b"] = { type: JSON_TYPE.STRING, str: "jjf" }; // THIS LINE } marked line will not compile failing with: json.d(8): Error: found ':' when expecting ';' following statement Is there any way to selectively initialize a struct while using it as AA value? The way I set "a" key works, but requires two lines instead of one and I have many such elements to set. I can't initialize all members of JSONValue, because there are many and I only need those two. -- Marek Janukowicz
ORM libraries out there
Does anyone know about any decent ORM (Object Relational Mapping or whatever it stands for) libraries for D? If someone actually tried some of those it would be a big plus. -- Marek Janukowicz
Re: Templated structs / variant values
Dicebot wrote: > On Tuesday, 20 August 2013 at 11:22:35 UTC, Marek Janukowicz > wrote: >>> if(is(type == Setting!U, U...)) >> >> This is not enough for me - I have many instantiations of >> Setting struct >> template and I need all of them, regardless of parameters they >> were >> instantiated with. > > Have you actually tried this snippet? It does exactly that. > "U..." is a pattern for variadic template argument list. > Constraint will match Setting instance with any number of any > template arguments. Yeah, that was a typical PEBKAC. I somehow assumed you use U, U... as dummy placeholders :) even that I know this syntax. Anyway, this works as expected, so thank you very much (and all the other that contributed). -- Marek Janukowicz
Re: Templated structs / variant values
Dicebot wrote: >>> Thanks, but how do I get the list of members that are of >>> instantiated >>> Setting struct type? If I do it like this: >>> >>> alias type = typeof(__traits(getMember, this, s)); >>> if (is ( type == Setting)) >>> >>> I get: >>> >>> Error: struct aa.Setting(T, string desc, T deflt) is used as a >>> type >> >> That's a good question. There's probably some smart >> template/is-expression syntax to strip out arguments and only >> leaving Setting. > > if(is(type == Setting!U, U...)) This is not enough for me - I have many instantiations of Setting struct template and I need all of them, regardless of parameters they were instantiated with. -- Marek Janukowicz
Re: Templated structs / variant values
H. S. Teoh wrote: > On Tue, Aug 20, 2013 at 01:09:16AM +0200, Marek Janukowicz wrote: >> Jacob Carlborg wrote: > [...] >> > In "settings" you should be able to: >> > >> > 1. Iterate over all fields of the type Setting using >> > __tratis(derivedMembers) >> >> How do I do that? My understanding of types in case of templates is >> really poor... If I do something like: >> >> foreach( s; __traits(derivedMembers, typeof(this))) { >> >> how do I go from "s" into type of this member (especially that a type >> is an instantiated struct template?). > > To get the type: > > alias type = typeof(__traits(getMember, this, s)); > > To get the value: > auto value = __traits(getMember, this, s); > > Or you can get both: > > auto value = __traits(getMember, this, s); > alias type = typeof(value); > > >> And more generally - how do I check the type of a variable? > > int x; > assert(is(typeof(x) == int)); Thanks, but how do I get the list of members that are of instantiated Setting struct type? If I do it like this: alias type = typeof(__traits(getMember, this, s)); if (is ( type == Setting)) I get: Error: struct aa.Setting(T, string desc, T deflt) is used as a type -- Marek Janukowicz
Re: Templated structs / variant values
Jacob Carlborg wrote: > On 2013-08-15 00:29, Marek Janukowicz wrote: >> I need to have a generalized "settings" functionality that should work >> like this: >> * I need to be able to add this to a class >> * each setting has its name, description, type and default value >> * I need to iterate over all settings for given object >> >> API would more or less look like: >> class A { >> ... here I somehow define a setting called "maxTime" >> } >> >> A a = new A(); >> >> auto b = a.settings["maxTime"].value; // b would contain default value, >> because it wasn't set explicitly yet >> string s = a.settings["maxTime"].description; // s would contain setting >> description >> a.settings["maxTime"].value = 10.seconds; // This would only work if >> maxTime setting is of type duration >> foreach( name, value; a.settings ) ... >> >> Now the problem that I have is with storing those settings. What I've >> come up with so far are either Variants or templated structs (either >> really templated and type parametrized structs returned from template >> functions). The problem with variants is that I don't know how to force >> the value to be of certain type (variant accepts anything). As for >> templates and structs I tried something like: >> >> auto setting (string name, string description, T, T deflt)() { >>struct Setting { >> string name = name; >> T value; >>} >>return Setting(name, deflt); >> } >> >> but then I don't know if there is any way to build an array of those to >> be able to iterate over them. >> >> I know generally there should be some kind of "setting definition" >> defined on class level that would keep shared information (like names and >> defaults) and then per-instance data containing just actual values, but I >> don't really care and any solution where this shared information is >> copied for every instance would also be fine. >> >> I know the description above is a bit messy (it's quite late now), but >> hopefully you can get the picture. Any ideas how to approach this >> problem? >> > > Perhaps you can do something like this: > > struct Setting (T, string desc) > { > T value; > enum description = desc; > alias value this; > > this (T value) > { > this.value = value; > } > } > > class A > { > Setting!(int, "foo bar") bar = 3; > > auto settings () > { > return Tuple!(typeof(bar), "bar")(bar); > } > } > > void main () > { > auto a = new A; > assert(a.bar.description == "foo bar"); > assert(a.bar.value == 3); > assert(a.bar == 3); > assert(a.settings.bar == 3); > } Thank you for this code, I narrowed my requirements a bit and ended up with this: struct Setting (T, string desc, T deflt) { T value = deflt; string description = desc; alias value this; this (T value) { this.value = value; } } class A { Setting!(int, "Some max int", 10) max; Setting!(string, "name", "default name") name; } This looks very neat to me: definition is provided via template parameters while the actual value is provided via argument. > In "settings" you should be able to: > > 1. Iterate over all fields of the type Setting using > __tratis(derivedMembers) How do I do that? My understanding of types in case of templates is really poor... If I do something like: foreach( s; __traits(derivedMembers, typeof(this))) { how do I go from "s" into type of this member (especially that a type is an instantiated struct template?). And more generally - how do I check the type of a variable? > 2. Create and return tuple of all these fields > > But then you won't be able to set the value via "settings". What I really is need is a JSON of name => value pairs and corresponding method to update the settings from such JSON structure. Or it may be AA with Variant values, it's really quite straightforward to convert between one and the other. But I have a problem of how to get a list of all fields of type Setting (as mentioned above). -- Marek Janukowicz
Templated structs / variant values
I need to have a generalized "settings" functionality that should work like this: * I need to be able to add this to a class * each setting has its name, description, type and default value * I need to iterate over all settings for given object API would more or less look like: class A { ... here I somehow define a setting called "maxTime" } A a = new A(); auto b = a.settings["maxTime"].value; // b would contain default value, because it wasn't set explicitly yet string s = a.settings["maxTime"].description; // s would contain setting description a.settings["maxTime"].value = 10.seconds; // This would only work if maxTime setting is of type duration foreach( name, value; a.settings ) ... Now the problem that I have is with storing those settings. What I've come up with so far are either Variants or templated structs (either really templated and type parametrized structs returned from template functions). The problem with variants is that I don't know how to force the value to be of certain type (variant accepts anything). As for templates and structs I tried something like: auto setting (string name, string description, T, T deflt)() { struct Setting { string name = name; T value; } return Setting(name, deflt); } but then I don't know if there is any way to build an array of those to be able to iterate over them. I know generally there should be some kind of "setting definition" defined on class level that would keep shared information (like names and defaults) and then per-instance data containing just actual values, but I don't really care and any solution where this shared information is copied for every instance would also be fine. I know the description above is a bit messy (it's quite late now), but hopefully you can get the picture. Any ideas how to approach this problem? -- Marek Janukowicz
Re: Namespace clash between modules
evilrat wrote: > is it necessary use multiple loggers? Of course - as the whole thing is about logging, which is not a critical part of the application - I could try another approach. However, I'd like to have per-module logger, because it's convenient to manage them this way (eg. I often need to change log level for particular module or I use different colors for a module). > maybe you should move ur > Logger instance to module scope(log module) and just handle log > sources some other way(i.e. add source string mapping in log > module)? It would be a viable solution, although definitely it would be more complicated than what I have now. > because i mean this clash is just due to multiple > instantions of this template Yes, I realize that multiple instantiations are the reason for this clash. However, being a D newbie I really wanted to ask the list first, hoping there might be some simple solution I don't know about. -- Marek Janukowicz
Namespace clash between modules
I implemented some generic logging module and want to use single Logger object per module. Some simplified excerpt from my code: module log; mixin template makeLogger( params,,, name ) { Logger logger; static this () { .. logger initialization... } } - module another; import log; mixin makeLogger!( , __MODULE__ ); logger( DEBUG, "aksjfakjdf" ); - module yet_another; import log; mixin makeLogger!( , __MODULE__ ); logger( INFO, "sdfsdfsdf" ); This works quite well, but if I import one module into another I get an obvious name clash on the variable name "logger". I have many modules where I want to use logging, so things like static import are not an option. Is there any pattern I could use here? -- Marek Janukowicz
Re: Is it possible using reflection or similar to extract only public method names from classes?
Gary Willoughby wrote: > Is it possible using reflection or similar to extract only public > method names from classes? I'm thinking how i would go about > writing a unit test/mocking framework, investigating how i can > gather information about such things before i manipulate them. See traits: http://dlang.org/traits.html Look for: getProtection, getVirtualFunctions, getVirtualMethods. -- Marek Janukowicz
Re: Getting number of messages in MessageBox
dennis luehring wrote: > the question is do the published counter then needs locking - and make > it slow for all - just for beeing getable? Good point - but I believe the code operating on the counter is synchronized already, so synchronized getter would not really slow things down. -- Marek Janukowicz
Re: Getting number of messages in MessageBox
Gabi wrote: > Why not go for the trivial solution - just increase/decrease a > counter for each push/pop message? Yeah, that's most likely what I'll end up with, but it's a pity such information exists and I only can't access it because someone decided to make it private... or should I file a bug (or rather feature request) about it? -- Marek Janukowicz
Re: Getting number of messages in MessageBox
Ali Çehreli wrote: > On 08/05/2013 04:18 PM, Marek Janukowicz wrote: >> I'm using std.concurrency message passing and I'd like to check which >> thread might be a bottleneck. The easiest would be check number of >> messages piled up for each of them, but I could not find a way to do >> that. Is it possible? Every detail about MessageBox seems to be hidden... > > Would setMaxMailboxSize() be helpful? > > void setMaxMailboxSize(Tid tid, size_t messages, bool function(Tid) > onCrowdingDoThis); > > You can set a limit (perhaps that is lower than normal operation) and > report whenever a particular Tid's MessageBox gets full. Well, while this could help a little, it's not really what I'm looking for. I'd like to dump message counts for various threads periodically and see how it fluctuates over time. With the solution you propose I could only check how often a certain limit is hit. -- Marek Janukowicz
Getting number of messages in MessageBox
I'm using std.concurrency message passing and I'd like to check which thread might be a bottleneck. The easiest would be check number of messages piled up for each of them, but I could not find a way to do that. Is it possible? Every detail about MessageBox seems to be hidden... -- Marek Janukowicz
Re: Socket.select interrupted system call because of GC
David Nadlinger wrote: > See > https://github.com/apache/thrift/blob/master/lib/d/src/thrift/server/transport/socket.d#L144 > for a production-tested implementation. When I wrote that code, > it wasn't possible to do this in a platform-independent way using > std.socket (see > https://github.com/apache/thrift/blob/master/lib/d/src/thrift/internal/socket.d > for the used constants), and I don't think it is now either. Thanks, I'll use this as my starting point. I'm concerned, however, that even though SA_RESTART option is set the interrupted call is not being restarted, but you need to handle that yourself. -- Marek Janukowicz
Re: String representation of enum value
Robik wrote: > I think std.conv.to!string is what are you looking for :) > > http://dpaste.dzfl.pl/e1c38f8f Wow, so simple, thanks -- Marek Janukowicz
String representation of enum value
Given following code: enum ErrorCode { BAD_REQUEST, UNKNOWN } ErrorCode code; is there any way to get string representation of code with regard to values defined in enum? I mean - if code == 0, I'd like to get a string "BAD_REQUEST", if it's == 1, I'd like to get string a "UNKNOWN". Of course I'd like to use something more consise and elegant than a switch :) -- Marek Janukowicz
Re: Socket.select interrupted system call because of GC
David Nadlinger wrote: >> but you should not reduce your sample down to maybe-incorrect >> (what it seems for me in this case) - the join wouldn't make >> your sample to big > > The example given is correct, as druntime guarantees that > non-daemon threads will run to completion before the program > terminates normally (see Thread.isDaemon). It's really nice to have some chat about the correctness of example code snippets, but can anyone help me with the original issue? :) -- Marek Janukowicz
Re: Socket.select interrupted system call because of GC
dennis luehring wrote: > Am 03.08.2013 08:38, schrieb Marek Janukowicz: >> void main () >> { >>writefln( "sa: %d", SA_RESTART ); >>(new Thread (&serverfunc)).start(); >>(new Thread (&clientfunc)).start(); >> } > > i have no idea to your main problem but firing threads without any join > on the threads in your main program seems very wrong to me - its like > allocating memory and let system kill process handle the zombies This is of course *not* my entire program (and in fact I made the whole snippet up just to showcase the problem). While I understand your concern it doesn't really make sense to use this piece of code for anything but reproducing the issue at hand. -- Marek Janukowicz
Socket.select interrupted system call because of GC
I have a program with one thread waiting on Socket.select call and another thread doing stuff causing GC to kick in. When this happens, Socket.select fails with "Interrupted system call". I found referenced to some old discussion and bug, but it seems to be long gone (I output SA_RESTART in my program to make sure it is defined). My program is attached below - it is happening on DMD 2.063 on Linux. import std.socket; import std.stdio; import core.thread; import core.sys.posix.signal; void serverfunc () { Socket listener = new TcpSocket (); listener.bind (new InternetAddress(1234)); listener.listen(1); SocketSet set = new SocketSet( 1 ); Socket.select( set, null, null ); writefln( "last error: %s", lastSocketError() ); } void clientfunc () { while( true ) new Object(); } void main () { writefln( "sa: %d", SA_RESTART ); (new Thread (&serverfunc)).start(); (new Thread (&clientfunc)).start(); } If I disable GC the problem does not occur. Any idea how to solve this? -- Marek Janukowicz
Thread-local copy of data structure
I have quite complicated data structure (class-based) and I need a copy of it in a Task (std.parallelism). There is a simplification of data structure and my program: class A { B [] arr; } class B { C c; } class C { A a; } void main () { a = new A(); ... // Further initialization of data structure auto taskObject = new TaskObject( a ); auto t = task(taskObject); taskPool.put( t ); } Now "a" in my task is the same as "a" in main thread and I'd like a local copy - to be precise I need to make changes to a in the task, but they should not affect main copy. Is it possible to somehow create copy automatically when creating a task, or do I need to create it myself? If the latter - is there anything in std lib that helps with creation of deep clones or an I completely on my own? -- Marek Janukowicz
Re: mixin string to template - advice needed
Thank for for your elaborated example - I especially liked the comments :) This really shed some light for me on how much information you can get from template "alias" parameter. I also didn't realize you can use small string mixins just for small snippets that are difficult to implement with a regular template. -- Marek Janukowicz
mixin string to template - advice needed
Hello I have a repetitive piece of code that I'm now generating using string mixin. I humbly ask someone more skilled with D to review the code and help me transforming it into regular template mixin (as I would gladly avoid string mixin if possible). string flaggedAttr(string type, string name, string capName, string upName ) { return " @property bool has" ~ capName ~" () { return (_wildcards & MatchWildcard." ~ upName ~") > 0; } @property bool has" ~ capName ~ " ( bool has ) { if (has) _wildcards |= MatchWildcard." ~ upName ~ "; else _wildcards &= ~MatchWildcard." ~ upName ~ "; return has; } @property " ~ type ~ " " ~ name ~ " () in { assert( has" ~ capName ~ "(), \"" ~ capName ~ " not set in wildcards\" ); } body { return _" ~ name ~ "; } @property " ~ type ~ " " ~ name ~ " (" ~ type ~ " val) { has" ~ capName ~ " = true; _" ~ name ~ " = val; return _" ~ name ~ "; } "; } ( ... and the in a struct ... ) mixin(flaggedAttr( "PortNumber", "inPort", "InPort", "IN_PORT" )); ( ... which results in ... ) @property bool hasInPort () { return (_wildcards & MatchWildcard.IN_PORT) > 0; } @property bool hasInPort ( bool has ) { if (has) _wildcards |= MatchWildcard.IN_PORT; else _wildcards &= ~MatchWildcard.IN_PORT; return has; } @property PortNumber inPort () in { assert( hasInPort(), "InPort not set in wildcards" ); } body { return _inPort; } @property PortNumber inPort (PortNumber port) { hasInPort = true; _inPort = port; return _inPort; } The problems I struggle to solve: * dynamic method names (like "hasInPort" created from argument "inPort") * different versions of argument string (eg. "InPort" and "IN_PORT" from argument "inPort") * getting value from enum (MatchWildcard) give the name of the value (eg. "IN_PORT") Thank you for any help