digitalmars.D.learn - Working with modules
- Colin Grogan (38/38) Feb 15 2013 Hi all,
- Dmitry Olshansky (15/38) Feb 15 2013 Another way is to create utils/_.d file that contains:
- Jonathan M Davis (10/17) Feb 15 2013 The only way that you can have a single import which imports multiple mo...
- Colin Grogan (16/39) Feb 15 2013 Ah, ok.
- Dicebot (6/20) Feb 15 2013 Not exactly. With given layout you will need to use "import
- Colin Grogan (7/32) Feb 15 2013 Ah ok, now I get it.
- Colin Grogan (8/37) Feb 15 2013 Compiled and ran it, and it printed out
- Jacob Carlborg (10/11) Feb 15 2013 Note that in Java you declare a package wheres in D you declare a module...
- Jonathan M Davis (11/31) Feb 15 2013 utils/logger.d would be utils.logger. utils/logger/logger.d would be
- Jeremy DeHaan (31/54) Feb 15 2013 I was actually going to post a similar question, but it looks
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (8/11) Feb 15 2013 There may be other ways of achieving that and I haven't given much
- Jeremy DeHaan (5/19) Feb 15 2013 That is really cool! I'll look into this more, but I am using an
- Jacob Carlborg (5/8) Feb 16 2013 There's also template mixins that could help:
- Jonathan M Davis (30/44) Feb 15 2013 me
- Jacob Carlborg (5/7) Feb 16 2013 How is that better than public imports. You'll get access to private
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (4/9) Feb 16 2013 I don't think it is better than any other solution. I got reminded of
- Jacob Carlborg (4/6) Feb 16 2013 Fair enough. :)
- Mike Parker (26/84) Feb 15 2013 On Saturday, 16 February 2013 at 03:50:12 UTC, Jeremy DeHaan
Hi all, I have a question regarding how to lay out my code. I wish to have a project directory structure that resembles java projects (As I'm comfortable working in that sort of environment For example: $PROJHOME |-/src <- Source code |-/lib <- third party libraries |-/bin <- Compiled binaries |-build.sh <- script to build my project and stick the binary into 'bin' directory So, my src directory is where all my source code is going. Under source code, im going to have a few different folders. This is where my problem occurs. To illustrate: $PROJHOME |-/src |- utils |- Logger.d |- Properties.d |- SSHTool.d |- engine I want to put Logger.d, Properties.d and SSHTool.d into the module 'utils'. However, D's module system wont allow that, keeps throwing back errors to me saying 'utils' is conflicting (or something similar, cant remember the exact error). So, I've done a bit of reading, and found out that I should put all those classes into once source file, and put that file in the module 'utils'. Now, thats all fine and dandy, but I expect by the end of this experiment I will have quite a lot of utility classes and I really dont want them all in one source file. It becomes unwieldy imo. Does anyone here have any alternatives for me so that in my 'engine' or 'main' classes I can simply write: import utils; and still have my source files neatly laid out in manageable chunks? Thanks in advance...
Feb 15 2013
15-Feb-2013 13:51, Colin Grogan пишет: [snip]This is where my problem occurs. To illustrate: $PROJHOME |-/src |- utils |- Logger.d |- Properties.d |- SSHTool.d |- engine I want to put Logger.d, Properties.d and SSHTool.d into the module 'utils'. However, D's module system wont allow that, keeps throwing back errors to me saying 'utils' is conflicting (or something similar, cant remember the exact error). So, I've done a bit of reading, and found out that I should put all those classes into once source file, and put that file in the module 'utils'.Now, thats all fine and dandy, but I expect by the end of this experiment I will have quite a lot of utility classes and I really dont want them all in one source file. It becomes unwieldy imo. Does anyone here have any alternatives for me so that in my 'engine' or 'main' classes I can simply write: import utils;Another way is to create utils/_.d file that contains: public import utils.Logger; public import utils.Properties; public import utils.SSHTool; and import it like this: import utils._; The other popular name for this module is 'all'.and still have my source files neatly laid out in manageable chunks?Yeah, community at large wants a cleaner way to do this. It just wasn't sorted out yet: http://wiki.dlang.org/DIP14 http://wiki.dlang.org/DIP15Thanks in advance...-- Dmitry Olshansky
Feb 15 2013
On Friday, February 15, 2013 10:51:00 Colin Grogan wrote:Does anyone here have any alternatives for me so that in my 'engine' or 'main' classes I can simply write: import utils; and still have my source files neatly laid out in manageable chunks?The only way that you can have a single import which imports multiple modules is if the module that you're importing publicly imports the other modules. And there is no way to do something like import utils.*; And remember that modules always correspond to files, and packages correspond to folders, so there's a one-to-one correspondance between what you'd import and what you'd put in the file system (unless you use public imports to make it so that importing a module imports stuff from outside that module). - Jonathan M Davis
Feb 15 2013
On Friday, 15 February 2013 at 10:01:35 UTC, Jonathan M Davis wrote:On Friday, February 15, 2013 10:51:00 Colin Grogan wrote:Ah, ok. So, I have my structure like so: $PROJHOME |-src |-utils |- Logger.d // contains "module utils.Logger" |- Props.d // contains "module utils.Props" |- utils.d // contains "module utils; public import utils.Logger, utils.Props;" Then, i just 'import utils' in my code. Or would I have to have Logger.d in a directory called src/utils/Logger/Logger.d to be able to declare the module 'utils.Logger'?Does anyone here have any alternatives for me so that in my 'engine' or 'main' classes I can simply write: import utils; and still have my source files neatly laid out in manageable chunks?The only way that you can have a single import which imports multiple modules is if the module that you're importing publicly imports the other modules. And there is no way to do something like import utils.*; And remember that modules always correspond to files, and packages correspond to folders, so there's a one-to-one correspondance between what you'd import and what you'd put in the file system (unless you use public imports to make it so that importing a module imports stuff from outside that module). - Jonathan M Davis
Feb 15 2013
On Friday, 15 February 2013 at 10:31:41 UTC, Colin Grogan wrote:Ah, ok. So, I have my structure like so: $PROJHOME |-src |-utils |- Logger.d // contains "module utils.Logger" |- Props.d // contains "module utils.Props" |- utils.d // contains "module utils; public import utils.Logger, utils.Props;" Then, i just 'import utils' in my code. Or would I have to have Logger.d in a directory called src/utils/Logger/Logger.d to be able to declare the module 'utils.Logger'?Not exactly. With given layout you will need to use "import utils.utils;" in your code. There are no package imports in D currently at all. Separating modules into directories is not needed and will actually break everything. D module system maps to file system entities. File is a module. Directory is a package.
Feb 15 2013
On Friday, 15 February 2013 at 10:40:57 UTC, Dicebot wrote:On Friday, 15 February 2013 at 10:31:41 UTC, Colin Grogan wrote:Ah ok, now I get it. Thanks for that everyone. Ill test it out once I get home. Cheers! I saw the wiki entry posted earlier with recommendations for different module/package management, is there any plans to implement any of these changes do you know?Ah, ok. So, I have my structure like so: $PROJHOME |-src |-utils |- Logger.d // contains "module utils.Logger" |- Props.d // contains "module utils.Props" |- utils.d // contains "module utils; public import utils.Logger, utils.Props;" Then, i just 'import utils' in my code. Or would I have to have Logger.d in a directory called src/utils/Logger/Logger.d to be able to declare the module 'utils.Logger'?Not exactly. With given layout you will need to use "import utils.utils;" in your code. There are no package imports in D currently at all. Separating modules into directories is not needed and will actually break everything. D module system maps to file system entities. File is a module. Directory is a package.
Feb 15 2013
Ok, I had a minute so I tested it out. I had the following:src/main.d: import utils._; void main(string[] args){ logger l = new logger(); props p = new props(); l.print(); p.print(); } src/utils/_.d module utils._; public import utils.props, utils.logger; src/utils/logger.d module utils.logger; import std.stdio; public class logger{ this(){} public void print(){ writefln("This is logger..."); } } src/utils/props.d module utils.props; import std.stdio; public class props{ this(){} public void print(){ writefln("This is props..."); } }Compiled and ran it, and it printed out This is logger... This is props... as I expected. That's perfect, solves my problem quite well I think! Thanks all!
Feb 15 2013
On 2013-02-15 12:04, Colin Grogan wrote:Ah ok, now I get it.Note that in Java you declare a package wheres in D you declare a module. If you have something like this in Java: // Baz.java package bar.foo; You would do this in D: // Baz.d module bar.foo.Baz; -- /Jacob Carlborg
Feb 15 2013
On Friday, February 15, 2013 11:31:40 Colin Grogan wrote:So, I have my structure like so: $PROJHOME |-src | |-utils | |- Logger.d // contains "module utils.Logger" |- Props.d // contains "module utils.Props" |- utils.d // contains "module utils; public import utils.Logger, utils.Props;" Then, i just 'import utils' in my code. Or would I have to have Logger.d in a directory called src/utils/Logger/Logger.d to be able to declare the module 'utils.Logger'?utils/logger.d would be utils.logger. utils/logger/logger.d would be utils.logger.logger. The file paths and the import paths are identical. It's just that the file paths have slashes, and the import paths have dots. And unlike Java, there is zero connection between classes and modules. You could have many classes in a single module or none at all. Also, it's common practice to use all lowercase for module and package names (primarily to avoid any risk of different OSes treating the casing differently I believe - i.e. Windows doesn't care about casing whereas *nix does; so, on Windows, you could screw up you're casing, and it would work, whereas on Linux, it wouldn't). - Jonathan M Davis
Feb 15 2013
On Friday, 15 February 2013 at 10:01:35 UTC, Jonathan M Davis wrote:On Friday, February 15, 2013 10:51:00 Colin Grogan wrote:I was actually going to post a similar question, but it looks like this would be a better place to post! I know that a module can only be defined once, but I feel like there could be times where it would be helpful to be able to have the same module defined in separate files and I have an example. Right now, I am working on a binding and I am making use of the package access modifier to allow me to use internal objects that the end user will not be able to access directly. Problem is, my source files have many classes and are pretty convoluted. If I could define the module more than once I could split the source files up and it would be easier to work on, but I would still be able to share package declared objects and methods between modules like I do now. If I put the source files into their own packages, they are now hidden from source files I want them to be used in. Here's what I mean: mainpackage.system mainpackage.window mainpackage.graphics Anything defined with package is accessible between these. But... mainpackage.system.thing1 mainpackage.system.thing2 mainpackage.window.thing3 etc... Now things defined as package in mainpackage.system.thing1 are only accessible in mainpackage.system, but can't be accessed in mainpackage.window. Thoughts?Does anyone here have any alternatives for me so that in my 'engine' or 'main' classes I can simply write: import utils; and still have my source files neatly laid out in manageable chunks?The only way that you can have a single import which imports multiple modules is if the module that you're importing publicly imports the other modules. And there is no way to do something like import utils.*; And remember that modules always correspond to files, and packages correspond to folders, so there's a one-to-one correspondance between what you'd import and what you'd put in the file system (unless you use public imports to make it so that importing a module imports stuff from outside that module). - Jonathan M Davis
Feb 15 2013
On 02/15/2013 07:50 PM, Jeremy DeHaan wrote:I know that a module can only be defined once, but I feel like there could be times where it would be helpful to be able to have the same module defined in separate filesThere may be other ways of achieving that and I haven't given much thought to your question but there is also the import expression: http://dlang.org/expression.html#ImportExpression If needed, you can include D files similar to C's #include: mixin (import ("part_of_my_module.d")); mixin (import ("another_part_of_my_module.d")); Ali
Feb 15 2013
On Saturday, 16 February 2013 at 04:14:41 UTC, Ali Çehreli wrote:On 02/15/2013 07:50 PM, Jeremy DeHaan wrote:That is really cool! I'll look into this more, but I am using an IDE which would get angry if I included them in my project as .d files and didn't put in a module name, but I think you're on to something here.I know that a module can only be defined once, but I feellike therecould be times where it would be helpful to be able to havethe samemodule defined in separate filesThere may be other ways of achieving that and I haven't given much thought to your question but there is also the import expression: http://dlang.org/expression.html#ImportExpression If needed, you can include D files similar to C's #include: mixin (import ("part_of_my_module.d")); mixin (import ("another_part_of_my_module.d")); Ali
Feb 15 2013
On 2013-02-16 05:19, Jeremy DeHaan wrote:That is really cool! I'll look into this more, but I am using an IDE which would get angry if I included them in my project as .d files and didn't put in a module name, but I think you're on to something here.There's also template mixins that could help: http://dlang.org/template-mixin.html -- /Jacob Carlborg
Feb 16 2013
On Friday, February 15, 2013 20:14:41 Ali =C3=87ehreli wrote:On 02/15/2013 07:50 PM, Jeremy DeHaan wrote: > I know that a module can only be defined once, but I feel like the=re> could be times where it would be helpful to be able to have the sa=me> module defined in separate files =20 There may be other ways of achieving that and I haven't given much thought to your question but there is also the import expression: =20 http://dlang.org/expression.html#ImportExpression =20 If needed, you can include D files similar to C's #include: =20 mixin (import ("part_of_my_module.d")); mixin (import ("another_part_of_my_module.d"));You can play games like this if you really want to, but in general, it = should=20 be kept in mind that modules in D are designed to have a one-to-one=20 correspondance with files, and packages are designed to have a one-to-o= ne=20 correspondance with directories. And in general, fighting that is just = going to=20 cause trouble and confusion. That doesn't necessarily mean that it shou= ld=20 never be done, but in most cases, it would be far better to just reorga= nize=20 your code so that it's not necessary. Also, AFAIK, mixing in imports is= a very=20 rare thing to do, so for the most part, people won't be expecting it, a= nd it=20 will likely cause maintenance issues for anyone else working on your pr= oject. What is more typically done when you need to split stuff up is to use i= nternal=20 modules which are only imported internally and are not presented as par= t of=20 the public API, but even that isn't terribly common, I don't think (but= unlike=20 mixing in imports, it's something that the standard library actually do= es in a=20 few places). - Jonathan M Davis
Feb 15 2013
On 2013-02-16 05:14, Ali Çehreli wrote:mixin (import ("part_of_my_module.d")); mixin (import ("another_part_of_my_module.d"));How is that better than public imports. You'll get access to private declarations but besides that. -- /Jacob Carlborg
Feb 16 2013
On 02/16/2013 04:58 AM, Jacob Carlborg wrote:On 2013-02-16 05:14, Ali Çehreli wrote:I don't think it is better than any other solution. I got reminded of this possibility; that's all. :) Alimixin (import ("part_of_my_module.d")); mixin (import ("another_part_of_my_module.d"));How is that better than public imports. You'll get access to private declarations but besides that.
Feb 16 2013
On 2013-02-16 15:12, Ali Çehreli wrote:I don't think it is better than any other solution. I got reminded of this possibility; that's all. :)Fair enough. :) -- /Jacob Carlborg
Feb 16 2013
On Saturday, 16 February 2013 at 03:50:12 UTC, Jeremy DeHaan wrote:I was actually going to post a similar question, but it looks like this would be a better place to post! I know that a module can only be defined once, but I feel like there could be times where it would be helpful to be able to have the same module defined in separate files and I have an example. Right now, I am working on a binding and I am making use of the package access modifier to allow me to use internal objects that the end user will not be able to access directly. Problem is, my source files have many classes and are pretty convoluted. If I could define the module more than once I could split the source files up and it would be easier to work on, but I would still be able to share package declared objects and methods between modules like I do now. If I put the source files into their own packages, they are now hidden from source files I want them to be used in. Here's what I mean: mainpackage.system mainpackage.window mainpackage.graphics Anything defined with package is accessible between these. But... mainpackage.system.thing1 mainpackage.system.thing2 mainpackage.window.thing3 etc... Now things defined as package in mainpackage.system.thing1 are only accessible in mainpackage.system, but can't be accessed in mainpackage.window. Thoughts?On Saturday, 16 February 2013 at 03:50:12 UTC, Jeremy DeHaan wrote:I was actually going to post a similar question, but it looks like this would be a better place to post! I know that a module can only be defined once, but I feel like there could be times where it would be helpful to be able to have the same module defined in separate files and I have an example. Right now, I am working on a binding and I am making use of the package access modifier to allow me to use internal objects that the end user will not be able to access directly. Problem is, my source files have many classes and are pretty convoluted. If I could define the module more than once I could split the source files up and it would be easier to work on, but I would still be able to share package declared objects and methods between modules like I do now. If I put the source files into their own packages, they are now hidden from source files I want them to be used in. Here's what I mean: mainpackage.system mainpackage.window mainpackage.graphics Anything defined with package is accessible between these. But... mainpackage.system.thing1 mainpackage.system.thing2 mainpackage.window.thing3 etc... Now things defined as package in mainpackage.system.thing1 are only accessible in mainpackage.system, but can't be accessed in mainpackage.window. Thoughts?I see this as more of a code architecture issue. It's up to you to decide which modules belong to which package, and that's that. If you see system and window as belonging to one package, then don't create subpackages. You can still split things up into separate modules if you need to: mainpackage.system mainpackage.systhing1 mainpackage.systhing2 mainpackage.window mainpackage.winthing3 You could keep your public-facing API in system and window or, if your design doesn't work that way, have things spread out over the various thing* modules and let system and window import them publicly. Either way, client code then imports system and window and pretends the rest don't exist. It would be nice to have a special module declaration to enforce this on the client side, something like: private module mainpackage.systhing1; Any module declared as such would not be importable outside of the package, but could still be explicitly imported into the namespace via a public import from another module in the same package.
Feb 15 2013