http://qs321.pair.com?node_id=495618

rir has asked for the wisdom of the Perl Monks concerning the following question:

It seems like it would good to have:
package non_main;
check the symbol table and warn if the non_main namespace exists. I mean that such a warning could be optionally turned on.

I will probably add a lint process to catch the ordinary package statements and that should serve me well enough.

But I am curious

Be well,
rir

Replies are listed 'Best First'.
Re: Namespaces contiguous in the entirety
by TimToady (Parson) on Sep 28, 2005 at 17:01 UTC
    We see enough value in the constraint that, by default, Perl 6 will warn on namespace reentry. However, recognizing that reopening namespaces is useful, we'll make it really easy to suppress that warning by adding some trait to the declaration of the package or module or class to express the intent of reopening or redefining. "is also" and "is instead" might work.

      {use strict "package"}++. Symbolic references to packages are problematic. Just avoid them?

      - tye        

      Just to be sure we mean the same thing. This syntax describes what I am trying to achieve:
      package this_package can not be reentered;
      Your is also or is instead seems to indicate creating aliases for a namespace. I like that idea a lot--in a few languages I wished I could simply capture intention during prototyping by:
      class ID_NUMBER is INT;
      and settle details later.

      Be well,
      rir

Re: Namespaces contiguous in the entirety
by Tanktalus (Canon) on Sep 28, 2005 at 04:45 UTC

    While you're at it, your lint process may want to catch that there should only be one package statement per file, and that package statement should match the filename, including path, from some entry in @INC, with directory separators becoming ::, and a .pm thrown on at the end. All of this is further convention that is usually a Good Practice (tm).

    Or, you could embrace the freedom that perl gives to do what you think is right instead of what Larry thinks is right. Which means not following convention when convention is getting in the way of getting your job done. I've had cause to buck convention in the past, and your lint would probably give me problems over it. The key is to allow people to do what needs to be done, as long as they acknowledge they're doing something strange. Just like we always "use strict", but have the ability to lexically scope "no strict" (preferably with a modifier, such as 'refs').

      Tanktalus, your tone seems to disparage my intentions. If you read my post as a request to change Perl then I was not clear, I would just like that effect. Given the nature of the problem the easiest technically correct code-fix probably is to hack the perl source and add a check and fail to where package statements are handled. That would likely be a fairly localized patch.

      Collision of module names is a issue. In my code, client code is invited to partition a problem by creating sub-classes. It is very possible that the same namespace could be inadvertently reused. I am not trying to enforce the common conventions of a Good Practice(TM).

      Be well, rir

      While you're at it, your lint process may want to catch that there should only be one package statement per file, and that package statement should match the filename, including path, from some entry in @INC, with directory separators becoming ::, and a .pm thrown on at the end.
      My (limited) reading of modules leads me to think this is overkill. I've seen multiple package statements in a module for classes/namespaces derived from the main module, but the package was too small to worry about creating separate files. (I wonder how many modules in the core distribution make use of multiple package statements?)

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

        That's actually kind of my point. Convention says this is what you're supposed to do. However, convention also allows for alternatives. Convention says that each package appears once, at the top of a .pm file of the same name where ::'s are converted to directory separators. Which means that you should only have one package per file, and that you should never overlap with others' packages.

        In reality, there can be valid reasons for bucking convention. Packages that are too small to worry about separate files is a valid one. Hiding a package is another one - e.g., how mirod hides XML::Twig::Elt inside the XML/Twig.pm. Although in this case, it may be partly because XML::Twig and XML::Twig::Elt are so tightly intertwined that there could be fun times in trying to compile them in separate units. Other cases may have tightly tied packages where using the wrong one first can't resolve BEGIN blocks appropriately. Or other tightly tied packages where the other packages would take longer to locate on disk than is worth it.

        I really don't have a problem with the OP's suggestion. As long as there is a clean and easy way to turn it off when I know what I'm doing. Such as what TimToady suggests.

        use CGI::Application; class CGI::Application is also { # stuff we want to add to the CGI::Application namespace. };
        This says, "Yes, I know there is already a CGI::Application, but I'm the human, and you're the dumb computer, so do what I tell you." Well, that's what it says if I do it. It might not be so snarky if others do it ;-) I don't have an issue with this - the extra typing required for the rare time I do it seems like a reasonable trade-off.

        I'm not sure if there will be any perl 6 diagnostics for packages classes in the wrong file, though, as I had suggested to the OP.

Re: Namespaces contiguous in the entirety
by broquaint (Abbot) on Sep 28, 2005 at 10:09 UTC
    The package statement notifies the compiler what the following lexical scope's default namespace will be. Warning on the existence of that namespace seems a little arbitrary from that perspective.
    HTH

    _________
    broquaint

      That is one way to look at it. I think it is more accurate to view it this way:
      1. The first package specific_name statement creates a namespace and enters it.
      2. Subsequent invocations simply reenter the namespace.
      Having had the challenge of trying to explain the difference between C declarations and definitions to newbies; I can see how losing the distinction in dwimery would appeal as design choice for a higher level language.

      My reply above to tanktalus gives more of my reason to view it this way.

      Be well,
      rir

        1. The first package specific_name statement creates a namespace and enters it.
        2. Subsequent invocations simply reenter the namespace.
        While you may view that as conceptually accurate, that is not really what happens, hence my confusion above. I don't think I've ever come across this being an issue, not least because I would imagine that if you called code on a class you thought had declared, when in fact you had redeclared an existing class, something would break rather loudly.

        I can't think of any obvious way to do this within perl, but as you say, it would probably fairly simple just to hack the perl source and recompile.

        HTH

        _________
        broquaint

Re: Namespaces contiguous in the entirety
by herveus (Parson) on Sep 28, 2005 at 12:01 UTC
    Howdy!

    *Why* would it be good to have the package statement warn if the symbol table for that package already exists?

    Just for grins, I have discerned that the package statement, by itself, appears to cause $::{<package>::} to spring into existence, so that is what you'd be looking for...but I don't see any general value in attempting to make repeated use of 'package X' warnable. In fact, switching the default namespace on the fly is a perfectly valid technique.

    yours,
    Michael
Re: Namespaces contiguous in the entirety
by adrianh (Chancellor) on Sep 28, 2005 at 08:58 UTC
    do other people see value in such a constraint?

    Personally no.

    I regularly have multiple packages in a single file and don't see it as a problem. If the package is small, and isn't part of a public API, then splitting it out to a separate file is often a waste of time.

    Package declarations are lexically scoped for a reason :-)

    Have multiple package declarations caused you problems in the past?

    Update: Bah. Ignore me. Misread the original node.

    I'd still ask whether multiple declarations of the same package have been causing problems? Personally I cannot recall an instance of this causing problems so would question the utility of such warnings.

Re: Namespaces contiguous in the entirety
by philcrow (Priest) on Sep 28, 2005 at 13:00 UTC
    We already get a nice warning if we enter an existing package and define a sub it already had. That's enough for me. Re-entering packages is essential for some of the things I do, since it simplifies patterns like the visitor.

    Phil