Re: What are (were) the most difficult parts of D?
On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote: What are you stuck at? What was the most difficult features to understand? etc. To make it more meaningful, what is your experience with other languages? Ali Learning D is almost a complete blur in my memory but I distinctly remember not really understanding is expressions well into even fiddling around with them inside the compiler.
Re: Why are structs and classes so different?
On Sunday, 15 May 2022 at 21:33:24 UTC, Ali Çehreli wrote: D programmers don't write move constructors or move assignment. Such concepts don't even exist. Never say never : https://github.com/dlang/DIPs/blob/master/DIPs/DIP1040.md Walter is one of the authors of the DIP Also, there's `opPostMove` already within the language
Re: What are (were) the most difficult parts of D?
On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote: What are you stuck at? What was the most difficult features to understand? etc. To make it more meaningful, what is your experience with other languages? Ali Immutability. Ended up having to do so many hundreds of casts to and from immutable(whatever) the amount of mental strain greatly exceeded whatever benefits the entire concept is supposed to offer. Safety? Performance, in a future compiler version? I don't know where it's at right now. But you'd think I could do something like load some data from disk, craft a few objects, mark them as immutable, and shove them in an array or associative array without it being a nightmare, but it isn't. Or, having an otherwise mutable class with a member that references an immutable class, but can change which immutable instance it's referencing, without having to cast away the immutability of the thing I'm trying to protect in the first place. So I just stopped doing it, and simply rely on the "just don't make mistakes" practice to avoid writing to things that shouldn't be written to now. C#'s concept of marking a class member as "readonly" feels a lot more like what I was hoping to get. It doesn't complain at me when I return something that's readonly and the receiving destination isn't expecting it to be readonly, and also I have more free reign over what I can do to it during the constructor phase before it becomes hands-off. Things look a lot cleaner without another set of parentheses around every variable too. On another topic, the lack of a good "delete" keyword doing what one would expect, when there's a perfectly good "new" without its matching existential companion. This, and the ways around it, have already been discussed to death though, but banging my head over trying to force deterministic memory management into the GC-controlled D universe did take its toll on a good year or two of productivity.
Re: Why are structs and classes so different?
On 5/15/2022 8:26 AM, Kevin Bailey wrote: I'm trying to understand why it is this way. Great question. The difference, in a nutshell, is a struct is a value type, and a class is a reference type. This difference permeates every facet their behavior. In C++, a struct can designed to be a value type or a reference type. But C++ does not recognize the difference, and so you can pass a reference type by value, which leads to all sorts of problems. You'll see C++ structs confused about what they are, as the designer didn't know the difference and would put a foot in both camps. A common example of this confusion is putting in virtual functions but neglecting to make the destructor virtual. D draws a hard distinction between the two, making it both self-documenting, and heading off all sorts of errors from misusing one as the other. A reference type is inherently a polymorphic type (i.e. virtual functions). Polymorphism via inheritance makes no sense for a value type. Copy constructors make no sense for a polymorphic type, but are sensible for a value type. And so on. A strong distinction between value and reference types has turned out well for D. Naturally, some people still want a type to be both a floor wax and a dessert topping, but D is purposely going to make it difficult to do that. P.S. Yes, you can pass a struct by reference with the `ref` keyword. That's not polymorphic behavior, though. P.P.S. Yes, you can allocate a class instance on the stack rather than the GC by using the `scope` storage class. It will still be a reference type, but the compiler won't allow that reference to live longer than its stack frame. Java will automagically allocate classes on the stack if it can determine it cannot escape.
Re: Why are structs and classes so different?
On Sunday, 15 May 2022 at 15:26:40 UTC, Kevin Bailey wrote: I've done some scripting in D over the years but I never dug into D until recently. I'm going through Learning D and I was reminded that structs and classes are so different. - struct methods are non-virtual while class methods are virtual - Thus, structs can't inherit, because how would you find the child's destructor given a parent pointer? - On the stack, structs by-value but classes are by-reference I'm trying to understand why it is this way. I assume that there's some benefit for designing it this way. I'm hoping that it's not simply accidental, historical or easier for the compiler writer. A virtual function call has to pass through a virtual function look-up, and thus there is (some) overhead involved. Thus, by design, structs avoid this overhead (completely). It's also (I think) another reason why D does not support multiple inheritance. Since you would need multiple virtual function tables.
Re: Why are structs and classes so different?
On Sunday, 15 May 2022 at 15:59:17 UTC, Alain De Vos wrote: Can i summarize , structs are value-objects which live on the stack. class instances are reference objects which live on the heap. the real difference, is that structs, being value types, are passed by value, and classes, being reference types, are passed by reference. this is the most important difference to be aware of. where they live in memory should be less of the programmers concern, and more an implementation issue (although some programmers will of course consider this as well). btw. where does a struct, inside a class live?
Re: Why are structs and classes so different?
On Sun, May 15, 2022 at 08:05:05PM +, Kevin Bailey via Digitalmars-d-learn wrote: [...] > But I asked a different question: Why can't I put a class object on > the stack? What's the danger? [...] You can. Use core.lifetime.emplace. Though even there, there's the theoretical problem of stack corruption: if you have an emplaced class object O and you try to assign a derived class object to it, you could end up trashing your stack (the derived object doesn't fit in the stack space allocated to store only a base class instance). Generally, though, the language would prevent this. In D this doesn't happen because emplace just gives you the class instance as a reference (to a stack location, but nonetheless), and reassignment just updates the reference, it doesn't actually overwrite the base class instance. T -- If it tastes good, it's probably bad for you.
Re: Why are structs and classes so different?
On 5/15/22 13:05, Kevin Bailey wrote: > I've been programming in C++ full time for 32 years Hi from an ex-C++'er. :) I managed to become at least a junior expert in C++ between 1996-2015. I don't use C++ since then. I still think my answer is the real one. My implied question remains: Why does C++ have struct and class disticnction? I know they have different default access specifications but does that warrant two kinds? I claim there are two types in C++ as well: value types and reference types. And types of an inheritance hirerachy are by convention reference types. As others reminded on this thread, C++ programmers follow guidelines to treat types of hierarchies as reference types. > so I'm familiar > with slicing. It doesn't look to me like there's a concern here. Slicing renders types of class hierarchies reference types. They can't be value types because nobody wants to pass a Cat sliced as an Animal. It's always a programmer error. All D does is (just like C# did) appreciate the differences between these two kinds and utilize existing keywords. > One question is, how should we pass objects - by value or by reference? > In C++, you can do either, of course, but you take your chances if you > pass by value - both in safety AND PERFORMANCE. D is very different from C++ when it comes to that topic: - Since classes are reference types, there is no issue with performance whatsoever: It is just a pointer copy behind the scenes. - Since structs are value types, they can be shallow-copied without any concern. (D disallows self-referencing structs.) Only when it matters, one writes the copy constructor or the post-blit. (And this happens very rarely.) - rvalues are moved by default. They don't get copied at all. (Only for structs because classes don't have rvalues.) > The bottom line is that > no one passes by value, even for PODs (although we may return even large > objects.) I know it very well. In reality, nobody should care unless it matters semantically: Only if the programmer wants to pass an object by reference it should be done so. For example, to mutate an object or store a reference to it. You must be familiar with the following presentation by Herb Sutter how parameter passing is a big problem. (Yet, nobody realizes until a speaker like Herb Sutter makes a presentation about it.) https://www.youtube.com/watch?v=qx22oxlQmKc&t=923s Such concerns don't exist in D especially after fixing the "in parameters" feature. Semantically, the programmer should say "this is an input to this function". The programmer should not be concerned whether the number of bytes is over a threshold for that specific CPU or twhether the copy constructor may be expensive. D does not have such issues. The programmer can do this: - Compile with -preview=in - Mark function parameters as in (the ones that are input): auto foo(in A a, in B b) { // ... } The compiler should deal with how to pass parameters. The programmer provides the semantics and D follows these rules: https://dlang.org/spec/function.html#in-params Although one of my colleagues advices me to not be negative towards C++, having about 20 years of experience with C++, I am confident C++ got this wrong and D got this right. D programmers don't write move constructors or move assignment. Such concepts don't even exist. In summary, if a programmer has to think about pass-by-reference, that programmer has been conditioned to think that way. It has always been wrong. Passing by reference should have been about semantics. (Herb Sutter uses the word "intent" in that presentation.) > But I asked a different question: Why can't I put a class object on the > stack? What's the danger? There is no danger. One way I like is std.typecons.scoped: import std.stdio; import std.typecons; class C { ~this() { writeln(__FUNCTION__); } } void main() { { auto c = scoped!C(); } writeln("after scope"); } > Note that operating on that object hasn't changed. If I pass by > reference, it's no different than if I had created a reference. (Off-topic: I always wonder whether pass-by-reference comes with performance cost. After all, the members of by-reference struct will have to be accessed through a pointer, right? Shouldn't pass-by-value be faster for certain types? I think so but I never bothered to check the size threshold below which to confidently pass-by-value.) > One might say, Well, if D creates by value, then it has to pass by > value. But it doesn't; it has the 'ref' keyword. That's only when one wants to pass a reference to an object. I blindly pass structs by-value. The reason is, I don't think any struct is really large to cost byte copying. It's just shallow copy and it works. (Note that there are not much copy constructors in D.) > I hope Ali's answer isn't the real reason. I would be sad if D risked > seg faults just to make class behavior "consistent". I don't unders
Re: Why are structs and classes so different?
On Sunday, 15 May 2022 at 20:05:05 UTC, Kevin Bailey wrote: One question is, how should we pass objects - by value or by reference? In C++, you can do either, of course, but you take your chances if you pass by value - both in safety AND PERFORMANCE. The bottom line is that no one passes by value, even for PODs (although we may return even large objects.) Pass struct instances by ref or by value as needed, just as you do in C++. For classes, you never have direct access to the instance. Your class reference is a handle (a pointer) that is always passed by value. But I asked a different question: Why can't I put a class object on the stack? What's the danger? I answered that one. You can put a class on the stack with `scope`. There is no danger in that. If you're wanting direct access to the class instance, like you would have with a struct, you don't have that in D. Classes are modeled on Java, not C++. Note that operating on that object hasn't changed. If I pass by reference, it's no different than if I had created a reference. Again, you never have direct access to the object instance. You always access it through the handle. One might say, Well, if D creates by value, then it has to pass by value. But it doesn't; it has the 'ref' keyword. Everything is passed by value unless the `ref` keyword is present. One might want to avoid passing by value accidentally. Ok, one could have D pass class objects by reference implicitly. How do you pass by value accidentally? By forgetting the `ref` keyword? I don't like things silently changing like that, so one might have D forbid all but pass by 'ref' or pointer for class objects. I don't understand where you're coming from here. How can things silently change? I hope Ali's answer isn't the real reason. I would be sad if D risked seg faults just to make class behavior "consistent". Where is the risk of seg faults? Are you referring to the fact that class references are default initialized to null?
Re: Why are structs and classes so different?
On Sunday, 15 May 2022 at 20:05:05 UTC, Kevin Bailey wrote: I've been programming in C++ full time for 32 years, so I'm familiar with slicing. It doesn't look to me like there's a concern here. Yes, slicing is not the issue. Slicing is a problem if you do "assignments" through a reference that is typed as the superclass… so references won't help. The original idea might have been that structs were value-types, but that is not the case in D. They are not, you can take the address… So what you effectively have is that structs follow C layout rules and D classes are not required to (AFAIK), but there is an ABI and C++ layout classes, so that freedom is somewhat limited… D classes also have a mutex for monitors. In an ideal world one might be tempted to think that classes were ideal candidates for alternative memory management mechanisms since they are allocated on the heap. Sadly this is also not true since D is a system level programming language and you get to bypass that "type characteristic" and can force them onto the stack if you desire to do so…
Re: Why doesn't this piece of code work?
On Sunday, 15 May 2022 at 15:27:32 UTC, SvGaming wrote: [...] It works if that code is the main function. But in the full program that is only one of the functions and is not the main function. Until you post your full programm ideally in a reduced form [1] everybody who is willing to help must guess wildly what the unposted parts of your program does and how it may cause the read to be seemingly skipped. ``` import std.stdio; import std.process; void foo () { writeln("Here is a list of your mounted drives: "); auto mounts = executeShell("cat /proc/mounts | grep media"); writeln(mounts.output); writef("Type the path to your USB drive: "); string cont = readln; writeln(cont); // there was no variable named "a" writeln("A file selection menu will now appear so you can select an ISO to write."); // auto seliso = executeShell("zenity --file-selection"); // writeln(seliso.output); } int main () { foo; return 0; } ``` Also works as expected. What does `strace` report? And what compiler/version do you use? [1] https://stackoverflow.com/help/minimal-reproducible-example
Re: Why are structs and classes so different?
Hi Mike (and Guillaume, since you posted the same link), Thanks for the long explanation. I've been programming in C++ full time for 32 years, so I'm familiar with slicing. It doesn't look to me like there's a concern here. There seem to be a couple different questions here. I suspect that you answered a different one than I asked. One question is, how should we pass objects - by value or by reference? In C++, you can do either, of course, but you take your chances if you pass by value - both in safety AND PERFORMANCE. The bottom line is that no one passes by value, even for PODs (although we may return even large objects.) But I asked a different question: Why can't I put a class object on the stack? What's the danger? Note that operating on that object hasn't changed. If I pass by reference, it's no different than if I had created a reference. One might say, Well, if D creates by value, then it has to pass by value. But it doesn't; it has the 'ref' keyword. One might want to avoid passing by value accidentally. Ok, one could have D pass class objects by reference implicitly. I don't like things silently changing like that, so one might have D forbid all but pass by 'ref' or pointer for class objects. In any case, this doesn't quite address the instantiate by value issue. If there's still a case where putting an object on the stack breaks, I would greatly appreciate seeing a few lines of example code. I hope Ali's answer isn't the real reason. I would be sad if D risked seg faults just to make class behavior "consistent". thx
Re: FTP LS
On Sunday, 15 May 2022 at 19:13:10 UTC, ikod wrote: Added LIST command in v2.0.8 Thanks!
Re: FTP LS
On Saturday, 14 May 2022 at 08:42:46 UTC, Anonymouse wrote: Before I go on duplicating effort, does anyone have anything that can access FTP beyond PUT and GET? I need to read file information from a NAS so I know if I should upload a file or not. `dlang-requests` has `Request.post` and `Request.get`, but seemingly no way to LS. Added LIST command in v2.0.8 ``` ᐅ cat source/app.d import std.stdio; import requests; void main() { auto rq = Request(); auto rs = rq.execute("LIST", "ftp://ftp.iij.ad.jp/pub/FreeBSD/";); writeln(rs.responseBody); } /tmp/ttt ᐅ dub run Running ttt -rw-rw-r--1 ftp ftp 4259 May 07 2015 README.TXT -rw-rw-r--1 ftp ftp35 May 12 09:00 TIMESTAMP drwxrwxr-x9 ftp ftp 169 Oct 05 2015 development -rw-r--r--1 ftp ftp 2871 May 11 10:00 dir.sizes drwxrwxr-x 22 ftp ftp 8192 May 09 23:00 doc drwxrwxr-x6 ftp ftp92 Jan 10 21:38 ports drwxrwxr-x 12 ftp ftp 237 Feb 06 2021 releases drwxrwxr-x 12 ftp ftp 237 May 05 18:00 snapshots ``` -- Support 🇺🇦!
Re: Why doesn't this piece of code work?
On 5/15/22 08:27, SvGaming wrote: > I am so confused right now. It works if that code is the main function. > But in the full program that is only one of the functions and is not the > main function. Could it be that the main() function exits before calling that other function? You can sprinkle simple writeln calls to figure out exactly where it goes wrong: void main() { writeln("entered main"); writeln("before calling foo"); foo(); writeln("exiting main"); } Ali
Re: Why are structs and classes so different?
On 5/15/22 08:26, Kevin Bailey wrote: > structs and classes are so different. I think a more fundamental question is why structs and classes both exist at all. If they could be the same, one kind would be sufficient. And the answer is there are value types and there are reference types in programming. Ali
Re: Why are structs and classes so different?
On Sunday, 15 May 2022 at 15:26:40 UTC, Kevin Bailey wrote: I'm trying to understand why it is this way. I assume that there's some benefit for designing it this way. I'm hoping that it's not simply accidental, historical or easier for the compiler writer. There's a problem that arises with pass-by-value subclasses called "object slicing". Effectively, it's possible to "slice off" members of superclasses. It's one of many pitfalls to be avoided in C++. There you typically find the convention of structs being used as POD (Plain Old Data) types (i.e., no inheritance) and classes when you want inheritance, in which case they are passed around to functions as references. For reference: https://stackoverflow.com/questions/274626/what-is-object-slicing D basically bakes the C++ convention into the language, with a class system inspired by Java. One problem that this causes is that I have to remember different rules when using them. This creates the additional load of learning and remembering which types are which from someone else's library. Of all the complexity we need to remember as programmers, this is fairly low on the totem pole. Simple rule: if you need (or want) inheritance, use classes. If not, use structs. A bigger problem is that, if I have a struct that I suddenly want to inherit from, I have to change all my code. You should generally know up front if you need inheritance or not. In cases where you change your mind, you'll likely find that you have very little code to change. Variable declarations, sure. And if you were passing struct instances to functions, you'd want to change the function signatures, but that should be the lion's share of what you'd need to change. After all, D doesn't use the `->` syntax for struct pointers, so any members you access would be via the dot operator. In addition to that work, in both of these cases, one could easily do it wrong: // Fine with a struct, fatal with a class. Foo foo; At least in C++, the compiler would complain. In D, not even a warning. You generally find out about that pretty quickly in development, though. That's a good reason to get into the habit of implementing and running unit tests, so if you do make changes and overlook something like this, then your tests will catch it if normal operation of the program doesn't. Why is it this way? What is the harm of putting a class object on the stack? I've answered the "why" above. As to the the second question, there's no harm in putting a class on the stack: ```d import std.stdio; class Clazz { ~this() { writeln("Bu-bye"); } } void clazzOnStack() { writeln("Entered"); scope c = new Clazz; writeln("Leaving"); } void main() { clazzOnStack(); writeln("Back in main"); } ``` You'll find here that the destructor of `c` in `clazzOnStack` is called when the function exits, just as if it were a struct. `scope` in a class variable declaration will cause it to the class to be allocated on the stack. Note, though, that `c` *still* a reference to the instance. You aren't manipulating the class instance directly. If you were to pass `c` to a function `doSomething` that accepts a `Clazz` handle, it makes no difference that the instance is allocated on the stack. `doSomething` would neither know nor care. `c` is a handle, so you aren't passing the instance directly and it doesn't matter where it's allocated. There's more to the story than just reference type vs. value type. Structs have deterministic destruction, classes by default do not (`scope` can give it to you as demonstrated above). [See my blog post on the topic](https://dlang.org/blog/2021/03/04/symphony-of-destruction-structs-classes-and-the-gc-part-one/) for some info. (And I'm reminded I need to write the next article in that series; time goes by too fast). Everyone has their own criteria for when to choose class and when to choose struct. For me, I default to struct. I consider beforehand if I need inheritance, and if yes, then I ask myself if I can get by without deterministic destruction. There are ways to simulate inheritance with structs, and ways to have more control over destruction with classes, so there are options either way.
Re: Why are structs and classes so different?
On Sunday, 15 May 2022 at 15:26:40 UTC, Kevin Bailey wrote: I'm trying to understand why it is this way. I assume that there's some benefit for designing it this way. I'm hoping that it's not simply accidental, historical or easier for the compiler writer. Perhaps someone more informed will chime in, but there is a reason to avoid object inheritance with value types, and force them to be reference types. https://stackoverflow.com/questions/274626/what-is-object-slicing If we want to avoid that problem, then object with inheritance and virtual functions have to be reference types. But you still need values types. So now you have both struct and class, like in C# (Hejlsberg, 2000). For an escape hatch, D has library ways to have structs with virtual functions (there is a DUB package for that), and classes on the stack (Scoped!T, RefCounted!T, a __traits).
Re: Why are structs and classes so different?
Can i summarize , structs are value-objects which live on the stack. class instances are reference objects which live on the heap.
Re: Why doesn't this piece of code work?
On Sunday, 15 May 2022 at 12:27:45 UTC, kdevel wrote: On Sunday, 15 May 2022 at 12:19:22 UTC, SvGaming wrote: [...] [...] Install the `strace` program (I assume you are running Linux) and start your program under strace: [...] I am so confused right now. It works if that code is the main function. But in the full program that is only one of the functions and is not the main function.
Why are structs and classes so different?
I've done some scripting in D over the years but I never dug into D until recently. I'm going through Learning D and I was reminded that structs and classes are so different. - struct methods are non-virtual while class methods are virtual - Thus, structs can't inherit, because how would you find the child's destructor given a parent pointer? - On the stack, structs by-value but classes are by-reference I'm trying to understand why it is this way. I assume that there's some benefit for designing it this way. I'm hoping that it's not simply accidental, historical or easier for the compiler writer. One problem that this causes is that I have to remember different rules when using them. This creates the additional load of learning and remembering which types are which from someone else's library. A bigger problem is that, if I have a struct that I suddenly want to inherit from, I have to change all my code. In addition to that work, in both of these cases, one could easily do it wrong: // Fine with a struct, fatal with a class. Foo foo; At least in C++, the compiler would complain. In D, not even a warning. Why is it this way? What is the harm of putting a class object on the stack?
decimal type in d
Hello, I want read decimal type from sql db, do some arithmetic operations inside D program and write it back to DB. Result need to be close to result as if this operations was performed in sql DB. Something like C# decimal. Exists this kind of library ind D? (ideally `pure @safe @nogc nothrow`).
Re: Why doesn't this piece of code work?
On Sunday, 15 May 2022 at 12:19:22 UTC, SvGaming wrote: [...] This code runs as expected. Strange. It does not for me. I even tried different compilers. It simply does not ask for user input here where it is supposed to: ```d writef("Type the path to your USB drive: "); string cont = readln; writeln(cont); // there was no variable named "a" ``` Install the `strace` program (I assume you are running Linux) and start your program under strace: ``` $ strace -f ``` Then examine the system calls. On my machine I get this: ``` [...] mmap(NULL, 4194304, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76beb000 read(4, "", 4096) = 0 --- SIGCHLD (Child exited) @ 0 (0) --- read(4, "", 4096) = 0 wait4(26713, [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 26713 close(4)= 0 munmap(0x77ff5000, 4096)= 0 write(1, "\n", 1 ) = 1 fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 10), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x77ff5000 write(1, "Type the path to your USB drive:"..., 33Type the path to your USB drive: ) = 33 read(0, ``` Here the program waits for input.
Re: Why doesn't this piece of code work?
On Sunday, 15 May 2022 at 12:13:14 UTC, kdevel wrote: On Sunday, 15 May 2022 at 11:10:41 UTC, SvGaming wrote: [...] ``` import std.stdio; import std.process; int main () { writeln("Here is a list of your mounted drives: "); auto mounts = executeShell("cat /proc/mounts | grep media"); writeln(mounts.output); writef("Type the path to your USB drive: "); string cont = readln; writeln(cont); // there was no variable named "a" writeln("A file selection menu will now appear so you can select an ISO to write."); // auto seliso = executeShell("zenity --file-selection"); // writeln(seliso.output); return 0; } ``` This code runs as expected. Strange. It does not for me. I even tried different compilers. It simply does not ask for user input here where it is supposed to: ```d writef("Type the path to your USB drive: "); string cont = readln; writeln(cont); // there was no variable named "a" ```
Re: Why doesn't this piece of code work?
On Sunday, 15 May 2022 at 11:10:41 UTC, SvGaming wrote: I want to ask the user to select their USB drive by typing the mount location. For some reason that does not work and just skips over the user input part. ```d void writeusb() { writeln("Here is a list of your mounted drives: "); auto mounts = executeShell("cat /proc/mounts | grep media"); writeln(mounts.output); writef("Type the path to your USB drive: "); string cont = readln; writeln(a); writeln("A file selection menu will now appear so you can select an ISO to write."); auto seliso = executeShell("zenity --file-selection"); writeln(seliso.output); } ``` I am clueless as to what I need to do here? Can anyone help? Just noticed i forgot to put the proper variable name to the input. Should not matter though. Also when I change it nothing changes.
Re: Why doesn't this piece of code work?
On Sunday, 15 May 2022 at 11:10:41 UTC, SvGaming wrote: I want to ask the user to select their USB drive by typing the mount location. For some reason that does not work and just skips over the user input part. ```d void writeusb() { writeln("Here is a list of your mounted drives: "); auto mounts = executeShell("cat /proc/mounts | grep media"); writeln(mounts.output); writef("Type the path to your USB drive: "); string cont = readln; writeln(a); writeln("A file selection menu will now appear so you can select an ISO to write."); auto seliso = executeShell("zenity --file-selection"); writeln(seliso.output); } ``` I am clueless as to what I need to do here? Can anyone help? ``` import std.stdio; import std.process; int main () { writeln("Here is a list of your mounted drives: "); auto mounts = executeShell("cat /proc/mounts | grep media"); writeln(mounts.output); writef("Type the path to your USB drive: "); string cont = readln; writeln(cont); // there was no variable named "a" writeln("A file selection menu will now appear so you can select an ISO to write."); // auto seliso = executeShell("zenity --file-selection"); // writeln(seliso.output); return 0; } ``` This code runs as expected.
Why doesn't this piece of code work?
I want to ask the user to select their USB drive by typing the mount location. For some reason that does not work and just skips over the user input part. ```d void writeusb() { writeln("Here is a list of your mounted drives: "); auto mounts = executeShell("cat /proc/mounts | grep media"); writeln(mounts.output); writef("Type the path to your USB drive: "); string cont = readln; writeln(a); writeln("A file selection menu will now appear so you can select an ISO to write."); auto seliso = executeShell("zenity --file-selection"); writeln(seliso.output); } ``` I am clueless as to what I need to do here? Can anyone help?