Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
November 26, 2019 how to implement a function in a different D source file | ||||
---|---|---|---|---|
| ||||
Hey, I'm very interested in this programming language, I already prefer it to C++ and if only i had adopted it years ago, but that's beside the point. I read a bunch of tuts today and the only thing I'm really stuck on at the moment is how to actually implement a function in a different file. the page here https://dlang.org/spec/function.html suggests you can implement a function in a different file, and a different tutorial somewhere else (or maybe the same site or even same page idr) mentioned the endeavour of no-bodied-functions as a way of presenting a black-box type of interface. But with the whole module namespace thing I'm a bit at a loss how to do this. Say I have main.d ex.d and ex2.d and I want to import ex, and call a function it declares, and implement the function in ex2.d and link the objects at the end so the linker is happy. I don't know how to do this and I can't find a straigh answer anywhere or any examples. so ? |
November 26, 2019 Re: how to implement a function in a different D source file | ||||
---|---|---|---|---|
| ||||
Posted in reply to Omar | On Tuesday, 26 November 2019 at 03:06:52 UTC, Omar wrote: > Hey, I'm very interested in this programming language, I already prefer it to C++ and if only i had adopted it years ago, but that's beside the point. > > I read a bunch of tuts today and the only thing I'm really stuck on at the moment is how to actually implement a function in a different file. > > the page here https://dlang.org/spec/function.html > suggests you can implement a function in a different file, and a different tutorial somewhere else (or maybe the same site or even same page idr) mentioned the endeavour of no-bodied-functions as a way of presenting a black-box type of interface. > > But with the whole module namespace thing I'm a bit at a loss how to do this. > Say I have main.d ex.d and ex2.d and I want to import ex, and call a function it > declares, and implement the function in ex2.d and link the objects at the end so the linker is happy. I don't know how to do this and I can't find a straigh answer anywhere or any examples. > > so ? First, here's exactly what you're asking for: $ cat ex1.d enum string admin = "Dave"; $ cat ex2.d import ex1; string greeting() { return "Hello, " ~ admin; } $ cat main.d import ex2; void main() { import std.stdio: writeln; writeln(greeting); } Three files that all import what they need, and can be compiled separately and then linked. $ dmd -c ex1 $ dmd -c ex2 $ dmd -c main $ dmd -ofmain main.o ex2.o ex1.o $ ./main Hello, Dave And dmd isn't cheating, as you can see by skipping the first two compiles: $ rm *.o $ dmd -c main $ dmd -ofmain main.o /usr/bin/ld: main.o: in function `_Dmain': main.d:(.text._Dmain[_Dmain]+0x5): undefined reference to `_D3ex28greetingFZAya' collect2: error: ld returned 1 exit status Error: linker exited with status 1 But you could also just compile everything together: $ rm *.o $ dmd -ofmain *.d $ ./main Hello, Dave If all of your code is in D, my received understanding is that this is a completely reasonable option. You could also use dub as your build system: Package recipe format (sdl/json) [json]: Name [main]: Description [A minimal D application.]: Author name [mipri]: License [proprietary]: MIT Copyright string [Copyright © 2019, mipri]: Add dependency (leave empty to skip) []: This'll create a new directory named 'main', and you can build and run a 'hello world' by running 'dub'. After moving some files around... $ cat source/movie/references/names.d module movie.references.names; enum string admin = "Dave"; $ cat source/movie/references/lines.d module movie.references.lines; string cantDoThat() { import movie.references.names: admin; return "I'm afraid I can't do that, " ~ admin; } $ cat source/app.d void main() { import movie.references.lines: cantDoThat; import std.stdio: writeln; writeln(cantDoThat); } Building and running it: $ dub Performing "debug" build using dmd for x86_64. main ~master: building configuration "application"... Linking... Running ./main I'm afraid I can't do that, Dave |
November 26, 2019 Re: how to implement a function in a different D source file | ||||
---|---|---|---|---|
| ||||
Posted in reply to Omar | On Tuesday, 26 November 2019 at 03:06:52 UTC, Omar wrote: > the page here https://dlang.org/spec/function.html > suggests you can implement a function in a different file ... > mentioned the endeavour of no-bodied-functions as a way of presenting a black-box type of interface. oh, that's what you were asking. Consider: $ cat interface/references.d module references; string greeting(); $ cat implementation/references.d module references; string greeting() { return "Hello, Dave"; } $ cat main.d import references; void main() { import std.stdio: writeln; writeln(greeting); } And trying to build it: $ dmd -c implementation/references.d $ dmd -Iinterface -c main.d $ dmd main.o references.o $ ./main Hello, Dave |
November 26, 2019 Re: how to implement a function in a different D source file | ||||
---|---|---|---|---|
| ||||
Posted in reply to mipri | On Tuesday, 26 November 2019 at 03:55:24 UTC, mipri wrote:
> On Tuesday, 26 November 2019 at 03:06:52 UTC, Omar wrote:
>> the page here https://dlang.org/spec/function.html
>> suggests you can implement a function in a different file
> ...
>> mentioned the endeavour of no-bodied-functions as a way of presenting a black-box type of interface.
>
> oh, that's what you were asking.
>
> Consider:
>
> $ cat interface/references.d
> module references;
>
> string greeting();
>
> $ cat implementation/references.d
> module references;
>
> string greeting() {
> return "Hello, Dave";
> }
>
> $ cat main.d
> import references;
>
> void main() {
> import std.stdio: writeln;
> writeln(greeting);
> }
>
> And trying to build it:
>
> $ dmd -c implementation/references.d
> $ dmd -Iinterface -c main.d
> $ dmd main.o references.o
> $ ./main
> Hello, Dave
The idiomatic way to do that is to put the interface in a "D interface" file (.di) and the implementation in a .d file:
foo/bar.di
foo/bar.d
Then, when importing foo.bar, the compiler will pick up the .di file automatically.
And you can actually have the compiler generate the interface file for you from a source file with the -H option.
|
November 26, 2019 Re: how to implement a function in a different D source file | ||||
---|---|---|---|---|
| ||||
Posted in reply to Omar | On Tuesday, 26 November 2019 at 03:06:52 UTC, Omar wrote:
> the page here https://dlang.org/spec/function.html
> suggests you can implement a function in a different file, and a different tutorial somewhere else mentioned the endeavour of no-bodied-functions as a way of presenting a black-box type of interface.
This is not a common pattern in d; the only reason it's used in c and c++ is that those languages don't have a real module system. However, the way it's done is with .di (d interface) files. Consider:
test.di:
module test;
void print_stuff();
main.d:
import test;
void main() {
print_stuff();
}
test.d:
module test;
void print_stuff() {
import std.stdio;
writeln("I'm stuff");
}
You can verify the compiler is reading from test.di by putting test.d in a different directory from main.d and test.di.
|
November 27, 2019 Re: how to implement a function in a different D source file | ||||
---|---|---|---|---|
| ||||
Posted in reply to Elronnd | Oh I see, it seems like the answers I'm getting imply that you have the option of a pure interface or pure implementation but not a mix. I see how I could elaborate more on what I was asking about. As long as you only import the file but not try to compile the same module twice right ? So just to be clear, in D you can't do something like. /+ a.d +/ void func1 () { /+ do stuff +/ } void func2 () { /+ do stuff +/ } void func3 () ; /+ b.d +/ void func_x1 () { /+ do stuff +/ } void func3 () { /+ true stuff +/ } this forks into a second question but I think still fits this thread as it could just be seen as another form of the same question. Is there a way to define some functions in the body of a class definition, and define others outside of it in other places in the source file ? example /+ top.d +/ import stuff = other_stuff ; class system { int a,b,c,d ; float x,y,z ; stuff.struct1 p,i,e ; stuff.struct2 l,t,v ; int test (int CMD) { /+ do stuff +/ } int maintenance (stuff.struct) { /+ do stuff +/ } int connect () ; stuff.struct3 eval (stuff.op[] pipeline) ; void reset (int node) ; void save (stuff.struct_x state) ; void exportFile (string name) ; void loadFromStream () ; void loadFromFile () ; } /+ implement those 7 functions here or in other files +/ |
November 28, 2019 Re: how to implement a function in a different D source file | ||||
---|---|---|---|---|
| ||||
Posted in reply to Omar | On Wednesday, 27 November 2019 at 23:32:34 UTC, Omar wrote: > this forks into a second question but I think still fits this thread as it could just be seen as another form of the same question. > Is there a way to define some functions in the body of a class definition, and define others outside of it in other places in the > source file ? No, there isn't. You have to define all of a class's methods in the class body. However, you can define free functions that can be called with the same syntax as methods using UFCS [1]. For example: import std.stdio; class C { void foo() { writeln("foo"); } } void bar(C c) { writeln("bar"); } void main() { C c; c.foo(); c.bar(); } The main limitation is that, because `bar` is really a free function and not a method, it will not be inherited by C's child classes, and therefore cannot be overridden. [1] https://dlang.org/spec/function.html#pseudo-member |
November 30, 2019 Re: how to implement a function in a different D source file | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | ok, thanks for the replies everyone ! I think i might try fiddling around with mixins and see how i like that. |
Copyright © 1999-2021 by the D Language Foundation