www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - 'package' and access from subpackages..

reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
The language spec says the following about 'package' protection:

"Package extends private so that package members can be accessed from code 
in other modules that are in the same package. This applies to the innermost 
package only, if a module is in nested packages."

What confuses me is the second sentence.  I interpret it as meaning that if 
you have:

pack1.pack2.a
pack1.pack2.b
pack1.c

that a package variable in pack1.pack2.a will be accessible from 
pack1.pack2.b, but not from pack1.c.  This makes sense to me.

But I don't know if or how those words -- "the innermost package only" --  
apply to the case when a package variable is declared in module c and one 
wants to access it from modules a or b.  Since it says "innermost", I'm 
inclined to believe that it was not written to cover the latter case, only 
the former case.

What I continually run into, however, is the latter case.  Say I'm 
redesigning the MiniD implementation so that it's not all in 3 modules like 
it was before.  So I split things out into several modules.  But this is a 
large library -- large compiler, complex interpreter.  Putting all the 
compiler functions or all the interpreter functions into one module is 
exactly what I'm trying to avoid, so I split them up over several modules 
and make the interdependent pieces 'package'.

Now I've got about 40 modules in one package and it's starting to get 
irritating.  So I'd like to start creating subpackages: one for the 
compiler, one for the interpreter, one for the standard libraries.  But the 
problem is that the interpreter needs some of the internal memory-allocation 
stuff, as does the compiler and even the stdlibs.  So what can I do?  I 
can't put the memory allocation stuff in a subpackage since then its package 
members can't be accessed from any other package.  But I also can't put it 
in the superpackage since no subpackages can access it.  I don't want to 
make that functionality public for obvious reasons.

If I were able to access package members from superpackages, however, this 
would be easy.  It also makes sense -- in the above hierarchy, pack1.pack2.a 
*is in* the package pack1, although indirectly, so it should have access to 
pack1.c's package members.

Until then I'm stuck writing my library one level deep and will probably end 
up with 50 to 60 modules in it.  Sigh. 
Aug 28 2008
next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Fri, 29 Aug 2008 02:52:41 +0400, Jarrett Billingsley  
<kb3ctd2 yahoo.com> wrote:

 The language spec says the following about 'package' protection:

 "Package extends private so that package members can be accessed from  
 code
 in other modules that are in the same package. This applies to the  
 innermost
 package only, if a module is in nested packages."

 What confuses me is the second sentence.  I interpret it as meaning that  
 if
 you have:

 pack1.pack2.a
 pack1.pack2.b
 pack1.c

 that a package variable in pack1.pack2.a will be accessible from
 pack1.pack2.b, but not from pack1.c.  This makes sense to me.

 But I don't know if or how those words -- "the innermost package only" --
 apply to the case when a package variable is declared in module c and one
 wants to access it from modules a or b.  Since it says "innermost", I'm
 inclined to believe that it was not written to cover the latter case,  
 only
 the former case.

 What I continually run into, however, is the latter case.  Say I'm
 redesigning the MiniD implementation so that it's not all in 3 modules  
 like
 it was before.  So I split things out into several modules.  But this is  
 a
 large library -- large compiler, complex interpreter.  Putting all the
 compiler functions or all the interpreter functions into one module is
 exactly what I'm trying to avoid, so I split them up over several modules
 and make the interdependent pieces 'package'.

 Now I've got about 40 modules in one package and it's starting to get
 irritating.  So I'd like to start creating subpackages: one for the
 compiler, one for the interpreter, one for the standard libraries.  But  
 the
 problem is that the interpreter needs some of the internal  
 memory-allocation
 stuff, as does the compiler and even the stdlibs.  So what can I do?  I
 can't put the memory allocation stuff in a subpackage since then its  
 package
 members can't be accessed from any other package.  But I also can't put  
 it
 in the superpackage since no subpackages can access it.  I don't want to
 make that functionality public for obvious reasons.

 If I were able to access package members from superpackages, however,  
 this
 would be easy.  It also makes sense -- in the above hierarchy,  
 pack1.pack2.a
 *is in* the package pack1, although indirectly, so it should have access  
 to
 pack1.c's package members.

 Until then I'm stuck writing my library one level deep and will probably  
 end
 up with 50 to 60 modules in it.  Sigh.

I agree. I have a library and interfaces are stored at the root of the package, like this: gui.control.Button.d gui.control.Label.d gui.control.TreeView.d etc However, platform-dependent implementations are stored one level deeper: gui.control.win32.ButtonImpl.d - defines a class that implements Button interface gui.control.win32.LabelImpl.d etc I want to define some methods as package, but in this case sub-package modules aren't able to access them. That's why they are public for now :(
Aug 28 2008
prev sibling next sibling parent Max Samukha <samukha voliacable.com.removethis> writes:
On Thu, 28 Aug 2008 18:52:41 -0400, "Jarrett Billingsley"
<kb3ctd2 yahoo.com> wrote:

Until then I'm stuck writing my library one level deep and will probably end 
up with 50 to 60 modules in it.  Sigh. 

I think many D users are having the same problem, me included.
Aug 28 2008
prev sibling next sibling parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 What I continually run into, however, is the latter case.  Say I'm 
 redesigning the MiniD implementation so that it's not all in 3 modules like 
 it was before.  So I split things out into several modules.  But this is a 
 large library -- large compiler, complex interpreter.  Putting all the 
 compiler functions or all the interpreter functions into one module is 
 exactly what I'm trying to avoid, so I split them up over several modules 
 and make the interdependent pieces 'package'.
 
 Now I've got about 40 modules in one package and it's starting to get 
 irritating.  So I'd like to start creating subpackages: one for the 
 compiler, one for the interpreter, one for the standard libraries.  But the 
 problem is that the interpreter needs some of the internal memory-allocation 
 stuff, as does the compiler and even the stdlibs.  So what can I do?  I 
 can't put the memory allocation stuff in a subpackage since then its package 
 members can't be accessed from any other package.  But I also can't put it 
 in the superpackage since no subpackages can access it.  I don't want to 
 make that functionality public for obvious reasons.
 
 If I were able to access package members from superpackages, however, this 
 would be easy.  It also makes sense -- in the above hierarchy, pack1.pack2.a 
 *is in* the package pack1, although indirectly, so it should have access to 
 pack1.c's package members.
 
 Until then I'm stuck writing my library one level deep and will probably end 
 up with 50 to 60 modules in it.  Sigh. 

I can see two approaches to packages: plain and hierarchical. D, like Java, uses the plain approach: each package is on its own, and packages communicate via public and protected interfaces. This necessitates introducing additional, documentation-level contracts on which packages of a library are interface and which are implementation details. A pre-compiled library can enforce this by supplying .di files only for interface modules. It also can encourage the proper use by supplying a single import module. Another approach is to have hierarchical packages, which sounds close to the concept of nested classes and C++ namespaces. So that inner packages have access to anything with package access in all outer packages. But how do the outer packages communicate with inner? Inner packages are required to have interfaces which are public for some outer packages but private for some more outer packages. I cannot see an easy solution here. -- SnakE
Aug 29 2008
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Sergey Gromov" <snake.scaly gmail.com> wrote in message 
news:MPG.2322860868338f629896b1 news.digitalmars.com...

 I can see two approaches to packages: plain and hierarchical.

 D, like Java, uses the plain approach: each package is on its own, and
 packages communicate via public and protected interfaces. This
 necessitates introducing additional, documentation-level contracts on
 which packages of a library are interface and which are implementation
 details.

 A pre-compiled library can enforce this by supplying .di files only for
 interface modules. It also can encourage the proper use by supplying a
 single import module.

 Another approach is to have hierarchical packages, which sounds close to
 the concept of nested classes and C++ namespaces. So that inner packages
 have access to anything with package access in all outer packages. But
 how do the outer packages communicate with inner? Inner packages are
 required to have interfaces which are public for some outer packages but
 private for some more outer packages. I cannot see an easy solution
 here.

I was thinking that you would put the more generic stuff towards the top of the package hierarchy and the more specialized stuff towards the bottom, so that the generic stuff wouldn't actually have to access the specialized stuff. I.e. you would declare interfaces in package.*, but you would implement them in package.impl.*.
Aug 29 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 "Sergey Gromov" <snake.scaly gmail.com> wrote in message 
 Another approach is to have hierarchical packages, which sounds close to
 the concept of nested classes and C++ namespaces. So that inner packages
 have access to anything with package access in all outer packages. But
 how do the outer packages communicate with inner? Inner packages are
 required to have interfaces which are public for some outer packages but
 private for some more outer packages. I cannot see an easy solution
 here.

I was thinking that you would put the more generic stuff towards the top of the package hierarchy and the more specialized stuff towards the bottom, so that the generic stuff wouldn't actually have to access the specialized stuff. I.e. you would declare interfaces in package.*, but you would implement them in package.impl.*.

Yes, I'd organize packages that way, too. Now you call xml.parse(blah). The xml.parse() wants to create an instance of xml.concreteparser.Implementation. That requires Implementation in xml.concreteparser to be visible to the xml package. So should Implementation be public? -- SnakE
Aug 29 2008
parent reply Don <nospam nospam.com.au> writes:
Sergey Gromov wrote:
 Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 "Sergey Gromov" <snake.scaly gmail.com> wrote in message 
 Another approach is to have hierarchical packages, which sounds close to
 the concept of nested classes and C++ namespaces. So that inner packages
 have access to anything with package access in all outer packages. But
 how do the outer packages communicate with inner? Inner packages are
 required to have interfaces which are public for some outer packages but
 private for some more outer packages. I cannot see an easy solution
 here.

the package hierarchy and the more specialized stuff towards the bottom, so that the generic stuff wouldn't actually have to access the specialized stuff. I.e. you would declare interfaces in package.*, but you would implement them in package.impl.*.

Yes, I'd organize packages that way, too. Now you call xml.parse(blah). The xml.parse() wants to create an instance of xml.concreteparser.Implementation. That requires Implementation in xml.concreteparser to be visible to the xml package. So should Implementation be public?

No. It should be 'package'.
Sep 11 2008
next sibling parent Sergey Gromov <snake.scaly gmail.com> writes:
Don <nospam nospam.com.au> wrote:
 Sergey Gromov wrote:
 Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 "Sergey Gromov" <snake.scaly gmail.com> wrote in message 
 Another approach is to have hierarchical packages, which sounds close to
 the concept of nested classes and C++ namespaces. So that inner packages
 have access to anything with package access in all outer packages. But
 how do the outer packages communicate with inner? Inner packages are
 required to have interfaces which are public for some outer packages but
 private for some more outer packages. I cannot see an easy solution
 here.

the package hierarchy and the more specialized stuff towards the bottom, so that the generic stuff wouldn't actually have to access the specialized stuff. I.e. you would declare interfaces in package.*, but you would implement them in package.impl.*.

Yes, I'd organize packages that way, too. Now you call xml.parse(blah). The xml.parse() wants to create an instance of xml.concreteparser.Implementation. That requires Implementation in xml.concreteparser to be visible to the xml package. So should Implementation be public?

No. It should be 'package'.

Let me define the package structure a bit clearer. There's an xml.parser.Parser class. It's in module parser, in package xml. There are other modules in package xml as well. There's an xml.concreteparser.mainmodule.ConcreteParser class. It's in concreteparser sub-package in xml package. There are other modules in concreteparser package responsible for the concrete parser implementation. Now xml.parser.Parser wants to create an instance of xml.concreteparser.mainmodule.ConcreteParser. Giving package access to ConcreteParser makes it visible to all the modules in concreteparser package but not in xml package. Now I'm all ears.
Sep 11 2008
prev sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
Don wrote:
 Sergey Gromov wrote:
 Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 "Sergey Gromov" <snake.scaly gmail.com> wrote in message
 Another approach is to have hierarchical packages, which sounds 
 close to
 the concept of nested classes and C++ namespaces. So that inner 
 packages
 have access to anything with package access in all outer packages. But
 how do the outer packages communicate with inner? Inner packages are
 required to have interfaces which are public for some outer packages 
 but
 private for some more outer packages. I cannot see an easy solution
 here.

top of the package hierarchy and the more specialized stuff towards the bottom, so that the generic stuff wouldn't actually have to access the specialized stuff. I.e. you would declare interfaces in package.*, but you would implement them in package.impl.*.

Yes, I'd organize packages that way, too. Now you call xml.parse(blah). The xml.parse() wants to create an instance of xml.concreteparser.Implementation. That requires Implementation in xml.concreteparser to be visible to the xml package. So should Implementation be public?

No. It should be 'package'.

I must disagree. The 'package' qualifier can provide visibility for the current package and subpackages, but not superpackages. Otherwise, a 'package' variable in my.deeply.nested.Module would be visible to modules in: my.deeply.nested my.deeply my . ie. it would be public. Conversely, I think it's reasonable that a 'package' variable in my.Module should be visible in: my my.deeply my.deeply.nested Because a package, to me, represents everything in the current package, which implicitly includes subpackages. Sean
Sep 11 2008
parent reply Don <nospam nospam.com.au> writes:
Sean Kelly wrote:
 Don wrote:
 Sergey Gromov wrote:
 Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 "Sergey Gromov" <snake.scaly gmail.com> wrote in message
 Another approach is to have hierarchical packages, which sounds 
 close to
 the concept of nested classes and C++ namespaces. So that inner 
 packages
 have access to anything with package access in all outer packages. But
 how do the outer packages communicate with inner? Inner packages are
 required to have interfaces which are public for some outer 
 packages but
 private for some more outer packages. I cannot see an easy solution
 here.

top of the package hierarchy and the more specialized stuff towards the bottom, so that the generic stuff wouldn't actually have to access the specialized stuff. I.e. you would declare interfaces in package.*, but you would implement them in package.impl.*.

Yes, I'd organize packages that way, too. Now you call xml.parse(blah). The xml.parse() wants to create an instance of xml.concreteparser.Implementation. That requires Implementation in xml.concreteparser to be visible to the xml package. So should Implementation be public?

No. It should be 'package'.

I must disagree. The 'package' qualifier can provide visibility for the current package and subpackages, but not superpackages. Otherwise, a 'package' variable in my.deeply.nested.Module would be visible to modules in: my.deeply.nested my.deeply my . ie. it would be public.

I would have thought that . isn't part of the package. So that a 'package' function would be usable within the library it was designed for, but would be private outside it. Conversely, I think it's reasonable that a
 'package' variable in my.Module should be visible in:
 
 my
 my.deeply
 my.deeply.nested
 
 Because a package, to me, represents everything in the current package, 
 which implicitly includes subpackages.

I think that's how it works, but IMHO it's pretty useless. It's the higher-level functions which use the lower-level ones; and normally the high level stuff is at a lower level in the heirarchy. Are there any use cases for package which works the other way around? When would it be good design for a subpackage to use a variable or function from a super package?
Sep 12 2008
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Don wrote:
 Sean Kelly wrote:
 Don wrote:
 Sergey Gromov wrote:
 Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 "Sergey Gromov" <snake.scaly gmail.com> wrote in message
 Another approach is to have hierarchical packages, which sounds 
 close to
 the concept of nested classes and C++ namespaces. So that inner 
 packages
 have access to anything with package access in all outer packages. 
 But
 how do the outer packages communicate with inner? Inner packages are
 required to have interfaces which are public for some outer 
 packages but
 private for some more outer packages. I cannot see an easy solution
 here.

the top of the package hierarchy and the more specialized stuff towards the bottom, so that the generic stuff wouldn't actually have to access the specialized stuff. I.e. you would declare interfaces in package.*, but you would implement them in package.impl.*.

Yes, I'd organize packages that way, too. Now you call xml.parse(blah). The xml.parse() wants to create an instance of xml.concreteparser.Implementation. That requires Implementation in xml.concreteparser to be visible to the xml package. So should Implementation be public?

No. It should be 'package'.

I must disagree. The 'package' qualifier can provide visibility for the current package and subpackages, but not superpackages. Otherwise, a 'package' variable in my.deeply.nested.Module would be visible to modules in: my.deeply.nested my.deeply my . ie. it would be public.

I would have thought that . isn't part of the package. So that a 'package' function would be usable within the library it was designed for, but would be private outside it. Conversely, I think it's reasonable that a
 'package' variable in my.Module should be visible in:

 my
 my.deeply
 my.deeply.nested

 Because a package, to me, represents everything in the current 
 package, which implicitly includes subpackages.

I think that's how it works, but IMHO it's pretty useless. It's the higher-level functions which use the lower-level ones; and normally the high level stuff is at a lower level in the heirarchy. Are there any use cases for package which works the other way around? When would it be good design for a subpackage to use a variable or function from a super package?

module `builder.compiler.parser` and module `builder.linker.readelf` both use module `builder.util`
Sep 12 2008
parent Don <nospam nospam.com.au> writes:
Robert Fraser wrote:
 Don wrote:
 Sean Kelly wrote:
 Don wrote:
 Sergey Gromov wrote:
 Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 "Sergey Gromov" <snake.scaly gmail.com> wrote in message
 Another approach is to have hierarchical packages, which sounds 
 close to
 the concept of nested classes and C++ namespaces. So that inner 
 packages
 have access to anything with package access in all outer 
 packages. But
 how do the outer packages communicate with inner? Inner packages are
 required to have interfaces which are public for some outer 
 packages but
 private for some more outer packages. I cannot see an easy solution
 here.

the top of the package hierarchy and the more specialized stuff towards the bottom, so that the generic stuff wouldn't actually have to access the specialized stuff. I.e. you would declare interfaces in package.*, but you would implement them in package.impl.*.

Yes, I'd organize packages that way, too. Now you call xml.parse(blah). The xml.parse() wants to create an instance of xml.concreteparser.Implementation. That requires Implementation in xml.concreteparser to be visible to the xml package. So should Implementation be public?

No. It should be 'package'.

I must disagree. The 'package' qualifier can provide visibility for the current package and subpackages, but not superpackages. Otherwise, a 'package' variable in my.deeply.nested.Module would be visible to modules in: my.deeply.nested my.deeply my . ie. it would be public.

I would have thought that . isn't part of the package. So that a 'package' function would be usable within the library it was designed for, but would be private outside it. Conversely, I think it's reasonable that a
 'package' variable in my.Module should be visible in:

 my
 my.deeply
 my.deeply.nested

 Because a package, to me, represents everything in the current 
 package, which implicitly includes subpackages.

I think that's how it works, but IMHO it's pretty useless. It's the higher-level functions which use the lower-level ones; and normally the high level stuff is at a lower level in the heirarchy. Are there any use cases for package which works the other way around? When would it be good design for a subpackage to use a variable or function from a super package?

module `builder.compiler.parser` and module `builder.linker.readelf` both use module `builder.util`

But builder.util is not a subpackage of builder.compiler, is it?
Sep 15 2008
prev sibling next sibling parent reply Christian Kamm <kamm-incasoftware removethis.de> writes:
Jarrett Billingsley wrote:
 If I were able to access package members from superpackages, however, this
 would be easy.  It also makes sense -- in the above hierarchy,
 pack1.pack2.a *is in* the package pack1, although indirectly, so it should
 have access to pack1.c's package members.

I agree and from a short look at the sources, it should be an easy change to access.c:hasPackageAccess. 1) Could this change break any existing code? I don't think so, but am not entirely sure. 2) If it can't break any code, can we get it applied D1? Christian
Aug 29 2008
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Christian Kamm" <kamm-incasoftware removethis.de> wrote in message 
news:g99i3t$2gfj$1 digitalmars.com...
 Jarrett Billingsley wrote:
 If I were able to access package members from superpackages, however, 
 this
 would be easy.  It also makes sense -- in the above hierarchy,
 pack1.pack2.a *is in* the package pack1, although indirectly, so it 
 should
 have access to pack1.c's package members.

I agree and from a short look at the sources, it should be an easy change to access.c:hasPackageAccess. 1) Could this change break any existing code? I don't think so, but am not entirely sure.

It would make what's currently an error not an error, so no, I don't think so.
 2) If it can't break any code, can we get it applied D1?

For some reason W doesn't seem to agree. He doesn't want *any* changes going into D1, breaking or not. But if it's not specified, I don't know how you can call it a "change," simply a "clarification." I.e. .tupleof used on structs with private members (which used to give an error in D1. I was unable to convince W when he fixed this in D2, but for some reason, he went ahead and changed it when someone else filed a bug report, go figure.)
Aug 29 2008
prev sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message 
news:g97a7k$u5a$1 digitalmars.com...

I've created a bugzilla entry for this, if you'd like to vote for it.

http://d.puremagic.com/issues/show_bug.cgi?id=2529 
Dec 20 2008
parent davidl <davidl 126.com> writes:
在 Sun, 21 Dec 2008 11:58:25 +0800,Jarrett Billingsley  
<kb3ctd2 yahoo.com> 写道:

 "Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message
 news:g97a7k$u5a$1 digitalmars.com...

 I've created a bugzilla entry for this, if you'd like to vote for it.

 http://d.puremagic.com/issues/show_bug.cgi?id=2529

It's pretty appealing to create another qualifier rule or something for this practical programming. I think it's quite important to have the ability to do a finer grain of packaging at least in the case of MiniD.
Dec 21 2008