Re: Converting multiple inheritance code into C ++ for D language
On Friday, 17 February 2017 at 23:24:57 UTC, Nicholas Wilson wrote: Something like this would be a goods use for struct multiple alias this, except that we haven't implemented that yet unfortunately. What's the deal with that? It seems someone made progress on this issue 2 years ago and then vanished. It's a fairly significant feature that's never been implemented!
Re: Converting multiple inheritance code into C ++ for D language
On Friday, 17 February 2017 at 23:31:41 UTC, Adam D. Ruppe wrote: On Friday, 17 February 2017 at 23:11:25 UTC, Jean Cesar wrote: so I changed the code to use interface but how would I do so I could use the constructor in the same way as such a C ++ code? Interfaces + mixin templates give you something very similar to multiple inheritance. You can have named functions in the mixin templates that do the work of the constructor, then call them from the real constructor. Yes I saw here that it uses interface to make multiple inheritance just like C#, but I did not understand what would this mixing?
Re: Converting multiple inheritance code into C ++ for D language
On Friday, 17 February 2017 at 23:11:25 UTC, Jean Cesar wrote: so I changed the code to use interface but how would I do so I could use the constructor in the same way as such a C ++ code? Interfaces + mixin templates give you something very similar to multiple inheritance. You can have named functions in the mixin templates that do the work of the constructor, then call them from the real constructor.
Re: Converting multiple inheritance code into C ++ for D language
On Friday, 17 February 2017 at 23:11:25 UTC, Jean Cesar wrote: import std.stdio; import std.string; I've been reading a bit about multi-inheritance in D, but I have to use interface like C # to use multiple inheritance, but I have the code in C ++ that I've been testing to understand how it would be possible to implement multi-inheritance constructor despite seemingly It does not represent many things so I changed the code to use interface but how would I do so I could use the constructor in the same way as such a C ++ code? Test1,2,3 would be the name of the class constructors in C ++ how to port completely to D so that it works the same way? import std.stdio; import std.string; class Test1 { protected: std::string _msg1; public: Test1( std::string msg1 ): _msg1( msg1 ){} }; class Test2 { protected: std::string _msg2; public: Test2( std::string msg2 ): _msg2( msg2 ){} }; class Test3 { protected: std::string _msg3; public: Test3( std::string msg3 ): _msg3( msg3 ){} }; class Test4: public Test1, public Test2, public Test3 { std::string _msg4; public: Test4( std::string msg1, std::string msg2 , std::string msg3, std::string msg4 ): Test1( msg1 ), Test2( msg2 ), Test3( msg3 ), _msg4( msg4 ){ } void show(); }; void Test4::show() { std::cout << this->_msg1 << this->_msg2 << this->_msg3 << this->_msg4 << "\n\n"; } int main() { Test4 teste("\n\tTeste1 ","Teste2 ","Teste3 ","Teste4"); teste.show(); return 0; } Like in c#, classes on D are reference types and all methods are virtual unless marked final. Also D only allows single inheritance for data members, but you can multiplly inherit methods from interfaces (think abstract classes). Something like this would be a goods use for struct multiple alias this, except that we haven't implemented that yet unfortunately.
Converting multiple inheritance code into C ++ for D language
import std.stdio; import std.string; I've been reading a bit about multi-inheritance in D, but I have to use interface like C # to use multiple inheritance, but I have the code in C ++ that I've been testing to understand how it would be possible to implement multi-inheritance constructor despite seemingly It does not represent many things so I changed the code to use interface but how would I do so I could use the constructor in the same way as such a C ++ code? Test1,2,3 would be the name of the class constructors in C ++ how to port completely to D so that it works the same way? import std.stdio; import std.string; class Test1 { protected: std::string _msg1; public: Test1( std::string msg1 ): _msg1( msg1 ){} }; class Test2 { protected: std::string _msg2; public: Test2( std::string msg2 ): _msg2( msg2 ){} }; class Test3 { protected: std::string _msg3; public: Test3( std::string msg3 ): _msg3( msg3 ){} }; class Test4: public Test1, public Test2, public Test3 { std::string _msg4; public: Test4( std::string msg1, std::string msg2 , std::string msg3, std::string msg4 ): Test1( msg1 ), Test2( msg2 ), Test3( msg3 ), _msg4( msg4 ){ } void show(); }; void Test4::show() { std::cout << this->_msg1 << this->_msg2 << this->_msg3 << this->_msg4 << "\n\n"; } int main() { Test4 teste("\n\tTeste1 ","Teste2 ","Teste3 ","Teste4"); teste.show(); return 0; }
Re: Error reading char in read
On Friday, 17 February 2017 at 21:34:16 UTC, ag0aep6g wrote: On 02/17/2017 09:24 PM, Ali Çehreli wrote: It's the Unicode character "U+FFFD REPLACEMENT CHARACTER", which is represented by 2 chars in D. It takes 3 `char`s to represent U+FFFD: void main() { import std.stdio; writeln("\uFFFD".length); /* prints "3" */ } Yes I also think about the possibility of the user to use the char definition to read a sequence of characters, but calm
Re: Error reading char in read
On 02/17/2017 09:24 PM, Ali Çehreli wrote: It's the Unicode character "U+FFFD REPLACEMENT CHARACTER", which is represented by 2 chars in D. It takes 3 `char`s to represent U+FFFD: void main() { import std.stdio; writeln("\uFFFD".length); /* prints "3" */ }
Re: Strange behaviour of rdmd vs. dmd concerning main function
On 02/17/2017 07:41 PM, berni wrote: The command that works is dmd a.d b.o where b.o is a precompiled c file, similar to https://github.com/dlang/druntime/blob/master/src/core/stdc/errno.c When using rdmd it doesn't work anymore. When I make rdmd --chatty, I can find the reason: b.o is ommited in the call of dmd. How can I make rdmd pass this parameter to dmd too? You have to pass the .o file before the .d file. rdmd interprets everything that comes after the .d file as arguments to the generated program.
Re: Error reading char in read
On 02/17/2017 12:05 PM, wiki wrote: > So I executed it here anyway but still it presents arbitrary characters > in the char .. Right. char[50] is not suitable for user interaction like that. Use string, char[], etc. > What I thought was to create a reader where I could receive, > Char, string, int, float, double, real, for my future codes That's already available in many different ways: readf, readln, formattedRead, etc. > I tried doing this to understand how the char reading was, it is > preferable to use strings but the language has some specific reader for > char? "%c" can be used to read char. (Although, I still think you want to read a string, not a single char.) import std.stdio; void main() { char c; readf("%c", ); } > minha frase na captura de char Sorry, Google Translate did not work for that one. :( There is a confusion here. You keep saying 'char' but � is not a char (i.e. one of the 8-bit types). It's the Unicode character "U+FFFD REPLACEMENT CHARACTER", which is represented by 2 chars in D. char is a UTF-8 code unit, not a "character" in the sense that I think you're using it. Ali
Re: scope with if
On Friday, 17 February 2017 at 20:06:19 UTC, berni wrote: I wonder if it's possible to do something like this: import std.stdio; void main(string[] args) { if (args[1]=="a") { write("A"); scope (exit) write("B"); } write("C"); } I expected the output to be ACB not ABC. I understand, that the scope ends at the end of the if, but I wonder, if it's possible to have a "conditional scope" or something like this. I found a workaround using "finally", but anyway I'm curious. could be useful to have something like scope(final) that would be the "final scope"
scope with if
I wonder if it's possible to do something like this: import std.stdio; void main(string[] args) { if (args[1]=="a") { write("A"); scope (exit) write("B"); } write("C"); } I expected the output to be ACB not ABC. I understand, that the scope ends at the end of the if, but I wonder, if it's possible to have a "conditional scope" or something like this. I found a workaround using "finally", but anyway I'm curious.
Re: Error reading char in read
On Friday, 17 February 2017 at 18:57:55 UTC, Ali Çehreli wrote: On 02/17/2017 07:48 AM, Jean Cesar wrote: import std.stdio; import std.string; auto read(C)(ref C c, char[80] message) if (isSomeChar!C) { writef("\n\t%s: ", message); c = strip(readf()); readf(" %s", ); return c; } void main() { char[50] message; read(message,"Digite Seu nome: "); writeln(message); } estou tentando fazer um leitor de vetor de char porem esta dando erro My recommendation is to read some tutorials as there are many large and small differences between D, C++, and Java. Some notes: - In D, char is UTF-8 code unit. Perhaps you want to read ubyte (or byte)? - isSomeChar is defined in std.traits. You must import std.traits if you want to use isSomeChar: https://dlang.org/phobos/std_traits.html - From the way you call read(), it looks like you want to read a char array (vector), not a single char. So, isSomeChar is wrong. - It is common to use the string type in D. string is an array of immutable chars. We can change my read() function to read char[] as well: - Static arrays like char[50] are different from slices like char[]. The read() examples I had given are incomplete: They should work with value types and dynamic strings but not with static arrays. Here is another read() that works with char arrays: import std.stdio; import std.string; import std.traits; import std.range; import std.algorithm; auto read(S)(ref S s, string message) if (isSomeString!S) { import std.string : strip; writef("%s: ", message); s = readln().strip(); return s; } auto read(S)(ref S s, string message) if (isStaticArray!S && isSomeChar!(ElementType!S)) { string tmp; read(tmp, message); // Clear the array s[] = typeof(s[0]).init; // Assign without going out of bounds const len = min(s.length, tmp.length); s[0..len] = tmp[0..len]; return s; } void main() { char[50] message; read(message,"Digite Seu nome: "); writeln(message); } However, you'll see that static arrays may not be suitable for reading text, as char[50] will never know how long the actual text is. Here is the output: Digite Seu nome: : Jean Jean\377\377\377[...] For that to work, you would have to rely on the old C representation of strings with the '\0' character: // Assign without going out of bounds const len = min(s.length, tmp.length); s[0..len] = tmp[0..len]; const nullChar = min(s.length - 1, len); s[nullChar] = '\0'; However, it still doesn't work because char[50] still has 50 characters: Jean^@\377\377[...] As you see, you better use 'string' (or its mutable version, char[]) for such text. And again, it will take a long time to go through these basics unless you start with some tutorials: https://tour.dlang.org/ For strings: https://tour.dlang.org/tour/en/basics/alias-strings Some books: https://wiki.dlang.org/Books Ali So I executed it here anyway but still it presents arbitrary characters in the char .. What I thought was to create a reader where I could receive, Char, string, int, float, double, real, for my future codes I tried doing this to understand how the char reading was, it is preferable to use strings but the language has some specific reader for char? minha frase na captura de char
Re: how to pass stderr to core.stdc.stdio.fileno
On Friday, 17 February 2017 at 19:36:50 UTC, berni wrote: What I didn't understand was that large box below write in stdio. Maybe, it's because I'm not familiar with templates yet. That's the function signature, listing the arguments, types, etc. On write, it is mostly empty, write is relatively simple, and i designed it more for complicated ones. Like my create window constructor: http://dpldocs.info/experimental-docs/arsd.simpledisplay.SimpleWindow.this.1.html there you can see a pretty traditional arguments list. Complicated templates can be more readable too, like sort: http://dpldocs.info/experimental-docs/std.algorithm.sorting.sort.html though the short answer is "give it an array", the long answer there explains what else it can take too. But when I click on the question mark in the corner I get an empty search result, which, of course, doesn't explain anything. yeah i haven't written that page yet
Re: how to pass stderr to core.stdc.stdio.fileno
On Friday, 17 February 2017 at 19:16:44 UTC, Adam D. Ruppe wrote: Yes, that is my documentation fork, it has a search feature if you do dpldocs.info/some_term and it tries to be easier to read and navigate, let me know how you like it! What I've seen so far, looks quite good. What I didn't understand was that large box below write in stdio. Maybe, it's because I'm not familiar with templates yet. But when I click on the question mark in the corner I get an empty search result, which, of course, doesn't explain anything.
Re: Error reading char in read
On 02/17/2017 07:48 AM, Jean Cesar wrote: import std.stdio; import std.string; auto read(C)(ref C c, char[80] message) if (isSomeChar!C) { writef("\n\t%s: ", message); c = strip(readf()); readf(" %s", ); return c; } void main() { char[50] message; read(message,"Digite Seu nome: "); writeln(message); } estou tentando fazer um leitor de vetor de char porem esta dando erro My recommendation is to read some tutorials as there are many large and small differences between D, C++, and Java. Some notes: - In D, char is UTF-8 code unit. Perhaps you want to read ubyte (or byte)? - isSomeChar is defined in std.traits. You must import std.traits if you want to use isSomeChar: https://dlang.org/phobos/std_traits.html - From the way you call read(), it looks like you want to read a char array (vector), not a single char. So, isSomeChar is wrong. - It is common to use the string type in D. string is an array of immutable chars. We can change my read() function to read char[] as well: - Static arrays like char[50] are different from slices like char[]. The read() examples I had given are incomplete: They should work with value types and dynamic strings but not with static arrays. Here is another read() that works with char arrays: import std.stdio; import std.string; import std.traits; import std.range; import std.algorithm; auto read(S)(ref S s, string message) if (isSomeString!S) { import std.string : strip; writef("%s: ", message); s = readln().strip(); return s; } auto read(S)(ref S s, string message) if (isStaticArray!S && isSomeChar!(ElementType!S)) { string tmp; read(tmp, message); // Clear the array s[] = typeof(s[0]).init; // Assign without going out of bounds const len = min(s.length, tmp.length); s[0..len] = tmp[0..len]; return s; } void main() { char[50] message; read(message,"Digite Seu nome: "); writeln(message); } However, you'll see that static arrays may not be suitable for reading text, as char[50] will never know how long the actual text is. Here is the output: Digite Seu nome: : Jean Jean\377\377\377[...] For that to work, you would have to rely on the old C representation of strings with the '\0' character: // Assign without going out of bounds const len = min(s.length, tmp.length); s[0..len] = tmp[0..len]; const nullChar = min(s.length - 1, len); s[nullChar] = '\0'; However, it still doesn't work because char[50] still has 50 characters: Jean^@\377\377[...] As you see, you better use 'string' (or its mutable version, char[]) for such text. And again, it will take a long time to go through these basics unless you start with some tutorials: https://tour.dlang.org/ For strings: https://tour.dlang.org/tour/en/basics/alias-strings Some books: https://wiki.dlang.org/Books Ali
Re: how to pass stderr to core.stdc.stdio.fileno
On Friday, 17 February 2017 at 16:08:11 UTC, Adam D. Ruppe wrote: Try fileno(core.stdc.stdio.stderr); to force it to use the C stderr object instead of the D one. Alternatively, fileno(stderr.getFP()) should do it too. http://dpldocs.info/experimental-docs/std.stdio.File.getFP.html Many thanks! That worked. And also thanks for the link. I didn't know if this docs yet. :-)
Re: Strange behaviour of rdmd vs. dmd concerning main function
Something similar happend now, but this time it works with dmd and rdmd produces the error: The command that works is dmd a.d b.o where b.o is a precompiled c file, similar to https://github.com/dlang/druntime/blob/master/src/core/stdc/errno.c When using rdmd it doesn't work anymore. When I make rdmd --chatty, I can find the reason: b.o is ommited in the call of dmd. How can I make rdmd pass this parameter to dmd too?
Re: how to pass stderr to core.stdc.stdio.fileno
On Friday, 17 February 2017 at 16:02:39 UTC, berni wrote: int no = fileno(stderr); Try fileno(core.stdc.stdio.stderr); to force it to use the C stderr object instead of the D one. Alternatively, fileno(stderr.getFP()) should do it too. http://dpldocs.info/experimental-docs/std.stdio.File.getFP.html
how to pass stderr to core.stdc.stdio.fileno
The following code doesn't work: int no = fileno(stderr); The error message is: test.d(7): Error: function core.stdc.stdio.fileno (shared(_IO_FILE)*) is not callable using argument types (File) How can I cast stderr to something, that fileno() accepts?
Error reading char in read
import std.stdio; import std.string; auto read(C)(ref C c, char[80] message) if (isSomeChar!C) { writef("\n\t%s: ", message); c = strip(readf()); readf(" %s", ); return c; } void main() { char[50] message; read(message,"Digite Seu nome: "); writeln(message); } estou tentando fazer um leitor de vetor de char porem esta dando erro
Re: Copying and moving directories
On Friday, 17 February 2017 at 11:40:35 UTC, Jonathan M Davis wrote: Well, there's a _long_ history of it being called rename on POSIX systems, and since the D function is a simple wrapper around rename, it makes sense that it's called rename, much as I agree that the name isn't the best for anyone not familiar with the C function. Regardless, changing it now would break code, and at this point, we pretty much never rename public symbols in Phobos just to improve their names. Nobody wants to rename `rename` :-) But an additional `move` function would be nice. [...] I agree. std.file needs more work.
Re: A bug?
On Wednesday, 15 February 2017 at 19:56:31 UTC, berni wrote: On Wednesday, 15 February 2017 at 16:11:36 UTC, drug wrote: No, you recursively call main() and get segfault (due to stack overflow) as expected I thought, that an stack overflow leeds to an exception. But that's not true, as I now see. Thanks for your answer. That's a language implementation and may not be true in *all* languages. Theoretically a stackoverflow cannot be a thrown exception (Even in languages where it appears so such as c#), because it would require space in the stack, which obviously you just overflowed, so there's none. That's why exceptions such as that would be reallocated at runtime before program start, but that may not be the case for all languages. I'm not sure what D does, but it seems like it does nothing, hence why there's no exception for it and you just end up with a segfault. Also remember that D is a system's programming language, so things like that may not be optimal in all environments and all operating systems.
Re: Copying and moving directories
On Friday, February 17, 2017 11:00:30 Chris via Digitalmars-d-learn wrote: > On Thursday, 16 February 2017 at 17:06:30 UTC, Jonathan M Davis > > wrote: > > Well, there's zero difference between renaming the file or > > directory and moving it. It's simply a difference in name. > > rename actually comes from POSIX, where rename is used in C > > code, and mv is used in the shell. So, I guess that you can > > blame POSIX. But there really isn't any reason to have a mv or > > move function in addition to rename. > > `mv` or `move` would be more intuitive. I actually looked for > names similar to the operations available in the shell (cp/copy, > mv/move). It took me a few minutes to realize I had to use > `rename` (which is poorly documented). But it is > counter-intuitive. When you use a GUI, `rename` doesn't change > the location. `rename` is a bit "techy", you have to go "wait a > minute, when you think about it, rename should do the same". But > that's not good enough for a library function. One of D's slogans > is `simple things should be simple`, so moving a file should be > `move(dir, toDir)`. Seriously, you don't want to spend much time > on stuff like that. Well, there's a _long_ history of it being called rename on POSIX systems, and since the D function is a simple wrapper around rename, it makes sense that it's called rename, much as I agree that the name isn't the best for anyone not familiar with the C function. Regardless, changing it now would break code, and at this point, we pretty much never rename public symbols in Phobos just to improve their names. > > If you want mv instead, just alias rename to mv. > > > > However, I would point out that rename has the problem (at > > least on *nix - not sure about Windows) that it can't move > > across filesystem boundaries. I think that at some point, an > > alternative which did work across filesystem boundaries was > > proposed, and that may have been called move. It's not > > currently in Phobos though. > > That is actually a bit of a problem. First, I might want to store > backup files on a different device. Second, loads of applications > need this nowadays to interact with MP3 players, ebook readers > etc. Yes, it is a problem, but we would have to implement our own function to do it, because the underlying system calls don't support moving files across filesystem boundaries. At that point, what you're fundamentally doing is copying the file or directory and then deleting the original. It's not actually possible to simply move files across filesystem boundaries (which is why the system call works the way it does). Any language or library which supports moving across file system boundaries implemented its own solution rather than simply using a system call. And we probably should add some sort of move function to std.file that works more like mv (leaving rename to wrap the system call and act like someone familiar with the POSIX function would expect while providing a more user-friendly - but somewhat less efficient - function for moving files from anywhere to anywhere), but thus far, no one has added such a function to Phobos. We don't even have one that copies recursively (there's a PR in limbo for that one, but there were issues with the implementation and disagreement on how it should work - I basically wanted it to act like cp - which the PR doesn't - whereas others thought that that was a terrible idea). So, while what std.file has is nice and cross-platform and more pleasant than dealing with the underlying system calls even when you don't care about being cross-platform, it could definitely use some work to make some aspects of it more user-friendly. Most of what is there are fairly thin wrappers around systems calls. Sadly, my workaround has generally been to use std.process to use cp or mv, but there are also plenty of cases where I would have had to do that anyway, because I needed sudo (which AFAIK can't be done without the shell - though I'd love to learn how if it is). - Jonathan M Davis
Re: Copying and moving directories
On Thursday, 16 February 2017 at 17:06:30 UTC, Jonathan M Davis wrote: Well, there's zero difference between renaming the file or directory and moving it. It's simply a difference in name. rename actually comes from POSIX, where rename is used in C code, and mv is used in the shell. So, I guess that you can blame POSIX. But there really isn't any reason to have a mv or move function in addition to rename. `mv` or `move` would be more intuitive. I actually looked for names similar to the operations available in the shell (cp/copy, mv/move). It took me a few minutes to realize I had to use `rename` (which is poorly documented). But it is counter-intuitive. When you use a GUI, `rename` doesn't change the location. `rename` is a bit "techy", you have to go "wait a minute, when you think about it, rename should do the same". But that's not good enough for a library function. One of D's slogans is `simple things should be simple`, so moving a file should be `move(dir, toDir)`. Seriously, you don't want to spend much time on stuff like that. If you want mv instead, just alias rename to mv. However, I would point out that rename has the problem (at least on *nix - not sure about Windows) that it can't move across filesystem boundaries. I think that at some point, an alternative which did work across filesystem boundaries was proposed, and that may have been called move. It's not currently in Phobos though. - Jonathan M Davis That is actually a bit of a problem. First, I might want to store backup files on a different device. Second, loads of applications need this nowadays to interact with MP3 players, ebook readers etc.
Re: Copying and moving directories
On Friday, February 17, 2017 08:48:03 Kagamin via Digitalmars-d-learn wrote: > On Thursday, 16 February 2017 at 17:06:30 UTC, Jonathan M Davis > > wrote: > > Well, there's zero difference between renaming the file or > > directory and moving it. It's simply a difference in name. > > Isn't there a difference? > I though > move("/path/dir1","dir2") moves folder to current directory and > changes its name to dir2 > rename("/path/dir1","dir2") leaves folder where it was and only > changes its name to dir2 No, rename does change the whole path, just like mv would. If you want to just change the last part of the path, then you need to supply the entire path again but just change the last part. e.g. this passes: import std.file; void main() { scope(exit) if("a".exists) rmdirRecurse("a"); scope(exit) if("c".exists) rmdirRecurse("c"); mkdirRecurse("a/b"); assert("a".exists); assert(!"c".exists); assert("a/b".exists); assert(!"a/c".exists); rename("a/b", "c"); assert("a".exists); assert("c".exists); assert(!"a/b".exists); assert(!"a/c".exists); } Maybe there's another language that declares a move function and a rename function like you describe, but POSIX has rename for C and mv for shell, and both of them change the whole path, and on POSIX systems, D has just wrapped the POSIX rename function, so its behavior is the same. http://www.unix.com/man-page/FreeBSD/2/rename/ https://linux.die.net/man/2/rename - Jonathan M Davis
Re: Copying and moving directories
On Thursday, 16 February 2017 at 17:06:30 UTC, Jonathan M Davis wrote: Well, there's zero difference between renaming the file or directory and moving it. It's simply a difference in name. Isn't there a difference? I though move("/path/dir1","dir2") moves folder to current directory and changes its name to dir2 rename("/path/dir1","dir2") leaves folder where it was and only changes its name to dir2