Keyword "package" prevents from importing a package module "package.d"

Jonathan M Davis newsgroup.d at jmdavisprog.com
Fri Nov 3 18:04:58 UTC 2023


On Friday, November 3, 2023 5:20:56 AM MDT Andrey Zherikov via Digitalmars-d-
learn wrote:
> On Friday, 3 November 2023 at 00:52:18 UTC, H. S. Teoh wrote:
> > Supposedly you can do this:
> >     /* Original: */
> >
> >     // pkg/mymodule.d
> >     module mymodule;
> >     ... // code here
> >
> >     // main.d
> >     import mymodule;
> >     void main() { ... }
> >
> >     /* Split */
> >
> >     // pkg/mymodule/pub_submod.d
> >     module mymodule.pub_submod;
> >     ... // code here
> >
> >     // pkg/mymodule/priv_submod.d
> >     module mymodule.priv_submod;
> >     ... // code here
> >
> >     // pkg/mymodule/package.d
> >     module mymodule;
> >     public import priv_submod;
> >
> >     // main.d
> >     import mymodule;
> >     void main() { ... }
> >
> > Barring the issues listed above, of course.
>
> I know how to do this with package.d but my question was about
> "package.d is bad design decision" - How would I do this
> refactoring without dedicated "main package file"?
> Python, for example, has __init__.py as well

You don't. package.d is the only solution that the language provides to
split up a module in place without breaking code, and in general, it works
just fine. The issues that Adam was complaining about relate to bad installs
where you end up with both the old mymodule.d file and mymodule/package.d on
someone's system. The language does not handle that well (and that should be
fixed), but as long as the new files are installed properly (which would
include removing all of the old ones first), there isn't a problem. The
issue came up with Phobos because of folks who assumed that they could just
unzip a dmd install on top of another one without removing the old one
first, which will always be risky business if the set of modules changes
(which could also include module removals without introducing a
corresponding package.d, though that only happens after an appropriate
deprecation period). However, because the list of modules usually only
grows, some folks had been getting away with it before and weren't expecting
issues when either modules were removed or when they ended up with both
std/datetime.d and std/datetime/package.d on their system, because they
didn't actually remove the old install first. But since they hadn't been
removing their old install first, they ran into issues when modules were
split up in-place.

Whatever the pros and cons are for package.d overall, the entire reason that
it exists is to allow you to replace a module with a package, and Walter
went with that solution, because it required minimal changes to the
language. All of the semantics with public imports are what you get
normally. It's just that the compiler now will import foo/package.d when you
say

import foo;

and foo/package.d exists instead of requiring that it be foo.d.

If you don't want to use package.d as a solution for breaking up a module,
then your only option is to do so by changing your modules in manner which
will involve the new modules being named something completely different.
E.G. mymodule.d becomes foo/a.d and foo/b.d, with public imports in
mymodule.d like you would have done in mymodule/package.d. You then either
deprecate everything in mymodule.d so that folks will eventually change
their code to use foo/a.d and foo/b.d directly, or you leave the code in the
weird situation of everything being in the foo package, but existing code
continues to import mymodule potentially forever.

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list