www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Can I create a package with friendly modules

reply forkit <forkit gmail.com> writes:
Is it possible to create a package.d, consisting of (for 
example), two modules, where each module can access private 
declarations within each other.

In essence, declaring 'a module level friendship', or a kind of 
'extended module' if you want.

I might still want to add another module to the package, that is 
NOT part of that friendship between those other two modules, but 
is otherwise related to the solution.
Jun 11 2022
next sibling parent forkit <forkit gmail.com> writes:
On Sunday, 12 June 2022 at 05:05:46 UTC, forkit wrote:

e.g. If I could something like this:

// foo_1.d
module foo_1
private int a; // a is private to module foo_1

// foo_2.d
module foo_2
private int b; // b is private to module foo_2

// foo.d
module foo[dependencies:foo_1, foo_2];
import std;
writeln a; // can call foo_1.a directly even those its private to 
that module
writeln b; // can call foo_2.b directly even those its private to 
that module
Jun 11 2022
prev sibling next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Sunday, 12 June 2022 at 05:05:46 UTC, forkit wrote:
 Is it possible to create a package.d, consisting of (for 
 example), two modules, where each module can access private 
 declarations within each other.

 In essence, declaring 'a module level friendship', or a kind of 
 'extended module' if you want.

 I might still want to add another module to the package, that 
 is NOT part of that friendship between those other two modules, 
 but is otherwise related to the solution.
- packagename -- package.d -- futuremodule.d --- subpackagename ---- friend1.d ---- friend2.d ``` // friend1.d module packagename.subpackagename.friend1; package void doSomethingFriendly(); /////// // friend2.d module packagename.subpackagename.friend2; import packagename.subpackagename.friend1; void doSomething() { doSomethingFriendly(); } /////// // package.d module packagename; public import packagename.subpackagename.friend1, packagename.subpackagename.friend2, packagename.futuremodule; ```
Jun 11 2022
parent reply forkit <forkit gmail.com> writes:
On Sunday, 12 June 2022 at 05:46:17 UTC, Mike Parker wrote:

I don't get it.

How does this enable one module to access the private parts of 
another module?

Isn't 'private' *always* private to the module?

The idea I had, was to be able to spread a 'module' over more 
than one file - for the purpose of encapsulating this and that in 
different physical files, while *still* protecting the 'private 
is private to the module' concept.

e.g.

// main module
module myMainModule [extends: mod1, mod2, mod3];

when I compile this module myMainModule, the compiler brings the 
extensions of this module, and treats it as a single module.

similar to the concept of bringing in different modules into a 
package, only more fine-grained.

But if D has a one-to-one mapping between a module and a file, 
and if private is always private to the one module, then this 
could never work.
Jun 12 2022
parent Mike Parker <aldacron gmail.com> writes:
On Sunday, 12 June 2022 at 23:29:29 UTC, forkit wrote:

 I don't get it.

 How does this enable one module to access the private parts of 
 another module?
It doesn't. But what you were describing in your post is package-level access. By keeping it the cross-module access in a subpackage, package is "private" to that subpackage.
 Isn't 'private' *always* private to the module?
Yes, which is why it doesn't allow cross-module access.
 The idea I had, was to be able to spread a 'module' over more 
 than one file - for the purpose of encapsulating this and that 
 in different physical files, while *still* protecting the 
 'private is private to the module' concept.
You can't spread modules across multiple files.
 But if D has a one-to-one mapping between a module and a file, 
 and if private is always private to the one module, then this 
 could never work.
Not with private. But what I described is the same effect.
Jun 12 2022
prev sibling next sibling parent Salih Dincer <salihdb hotmail.com> writes:
On Sunday, 12 June 2022 at 05:05:46 UTC, forkit wrote:
 Is it possible to create a package.d, consisting of (for 
 example), two modules, where each module can access private 
 declarations within each other.
For this to be possible: You must first collect all modules in the directory with the same name as the module. Then you have to declare them with public import in package.d. If there are module specific things, you isolate them with package. Finally, compile it like this:
 dmd main myproject/mymodule
**main.d for example** ```d import myproject.mymodule; void main() { S s; // ok //P p // Error: undefined identifier `P` auto p = packageTest(); //ok } ``` --- **package.d for example** ```d module myproject.mymodule; public { import myproject.mymodule.module1; import myproject.mymodule.module2; import myproject.mymodule.module3; } ``` --- **module1.d for example** ```d module myproject.mymodule.module1; struct S { int i; } auto packageTest() { return P(); } package { struct P { int i; } } ``` SDB 79
Jun 12 2022
prev sibling parent reply Tejas <notrealemail gmail.com> writes:
On Sunday, 12 June 2022 at 05:05:46 UTC, forkit wrote:
 Is it possible to create a package.d, consisting of (for 
 example), two modules, where each module can access private 
 declarations within each other.

 In essence, declaring 'a module level friendship', or a kind of 
 'extended module' if you want.

 I might still want to add another module to the package, that 
 is NOT part of that friendship between those other two modules, 
 but is otherwise related to the solution.
You can use `package(qualifiedIdentifier)` to satisfy this to a greater extent Directory structure: ```sh src | |--- main_file.d | |---parent | |--- driver.d | |--- package.d | |--- thing | |--- package.d | |--- first.d | |--- second.d | |--- third.d ``` Code : `src/main_file.d`: ```d import parent; void main() { func(); } ``` `src/parent/package.d`: ```d module parent; public import driver; ``` `src/parent/driver.d`: ```d module parent.driver; import thing; void func() { S s; // from third.d auto t = first.a; // from second.d auto l = second.dbl; // from first.d } ``` `src/parent/thing/package.d`: ```d module parent.thing; public import first, second, third; ``` `src/parent/thing/first.d`: ```d module thing.first; import second; static this() { a = second.g; // can also access symbols within neighbouring modules } package(parent): int a; int b; string c; ``` `src/parent/thing/second.d`: ```d module thing.second; package(parent): int g; char p; double dbl; ``` `src/parent/thing/third.d`: ```d module thing.third; package(parent): struct S { int a; char c; string s; } private S private_struct; // can't access via parent package, since marked private ``` You run it via: `dmd -i -I=./parent -I=./parent/thing main_file.d` (I'm pretty sure it'll look far prettier using `dub`) Here, all the symbols that are within package `thing` are visible to package `parent` as well, but not visible to any other package/module
Jun 12 2022
parent Salih Dincer <salihdb hotmail.com> writes:
On Monday, 13 June 2022 at 06:05:03 UTC, Tejas wrote:
 Directory structure:
 ```sh

 src
 |
 |--- main_file.d
 |
 |---parent
       |
       |--- driver.d
       |
       |--- package.d
       |
       |--- thing
              |
              |--- package.d
              |
              |--- first.d
              |
              |--- second.d
              |
              |--- third.d
 ```

 Code :
 `src/main_file.d`:
 ```d
 import parent;

 void main()
 {
 	func();
 }
 ```

 `src/parent/package.d`:
 ```d
 module parent;

 public import
 	driver;
 ```

 `src/parent/driver.d`:
 ```d
 module parent.driver;

 import thing;

 void func()
 {
 	S s;			// from third.d
 	auto t = first.a;	// from second.d
 	auto l = second.dbl;	// from first.d
 }
 ```

 `src/parent/thing/package.d`:
 ```d
 module parent.thing;

 public import
 	first,
 	second,
 	third;
 ```

 `src/parent/thing/first.d`:
 ```d
 module thing.first;

 import second;

 static this()
 {
 	a = second.g; // can also access symbols within neighbouring 
 modules
 }
 package(parent):
 int a;
 int b;
 string c;
 ```

 `src/parent/thing/second.d`:
 ```d
 module thing.second;

 package(parent):

 int g;
 char p;
 double dbl;
 ```

 `src/parent/thing/third.d`:
 ```d
 module thing.third;

 package(parent):

 struct S
 {
 	int a;
 	char c;
 	string s;
 }

 private S private_struct; // can't access via parent package, 
 since marked private
 ```

 You run it via:
 `dmd -i -I=./parent -I=./parent/thing main_file.d`
 (I'm pretty sure it'll look far prettier using `dub`)

 Here, all the symbols that are within package `thing` are 
 visible to package `parent` as well, but not visible to any 
 other package/module
Thanks, we all appreciate your efforts... SDB 79
Jun 16 2022