A long shot, but putting it out there -- looking for a way to provide privacy based on a common relative package scope.
So, for example, is there a way to use private[foo] for packages com.company1.foo and com.company2.foo where each package will have access to the other foo package based on their "foo-ness"
Unlikely, but would be nice, have a private[model] used in dependent sbt projects that could really benefit from such a relative privacy.
You cannot do this. From the language spec (2.9):
The modifier can be qualified with an identifier C (e.g. private[C]) that must
denote a class or package enclosing the definition
So the best you can hope for is a shared common package. For the two given examples, com.company1.foo, and com.company2.foo the most restrictive shared root is com; private[com] would be the best you could do.
I don't think this is possible, since foo is just an alias for one specific fully named package in any given scope.
So to packages with names ending in .foo don't have much more in common than two packages containing the letter e in their names.
Related
I work with multiple grammars in the repl. The grammars use same names for some of their rules.
One of the documentation recipes mentions full qualification, to disambiguate type annotations in function pattern matching (it's in a note of the load function, but not in the code of this page - the .jar has it correct). But that might become tedious, so maybe there is aliasing for imports (like in Python import regex as r)?! And using full qualification in the first argument of the parse function doesn't seem to help to disambiguate all parse rules that are invoked recursively, parse(#lang::java::\syntax::Java18::CompilationUnit, src). At least it produces weird errors if I also import lang::java::\syntax::Java15.
In general, what is a safe way to handle symbols from different modules with same names?
Alternatively, is there a way to "unload" a module in the repl?
Some background information:
Rascal modules are open for reasons of extensibility, in particular data, syntax definitions and overloaded functions can be extended by importing another module; In this way you can extend a language and its processing functions by importing another module and adding rules and function alternatives at leisure.
There is a semantic difference between importing and extending a module. In particular import is not transitive and fuses only the uses of a name inside the importing module, while extend is transitive and also fuses recursive uses of a name in the module that is extended. So for extending a language, you'd default to using extend, while for using a library of functions you'd use import.
We are planning to remove the fusing behavior from import completely in one of the releases of 2020. After this all conflictingly imported non-terminal names must be disambiguated by prefixing with the module name, and prefixing will not have a side-effect of fusing recursively used non-terminals from different modules anymore. Not so for extend, which will still fuse the non-terminal and functions all the way.
all the definitions in a REPL instance simulate the semantics of the members of a single anonymous module.
So to answer your questions:
it's not particularly safe to handle symbols from different imported modules with the same name, until we fix the semantics of import that is.
the module prefix trick only works "top-level", below this the types are fused anyway because the code which reifies a non-terminal as a grammar does not propagate the prefix. It wouldn't know how.
Unimporting a module:
rascal>import IO;
ok
rascal>println("x");
x
ok
rascal>:un
undeclare unimport
rascal>:unimport IO
ok
rascal>println("x");
|prompt:///|(0,7,<1,0>,<1,7>): Undeclared variable: println
probably one of the least used features in the environment; caveat emptor!
To work around these issues, a way is to write functions inside a different module for every separate language/language version, and create a top module which imports these if you want to bundle the functionality in a single interface. This way, because import is not transitive, the namespaces stay separate and clean. Of course this does not solve the REPL issue; the only thing I can offer there is to start a fresh REPL for each language version you are playing with.
If I am not mistaken, once a package has been analyzed, its visibility is global (like that of a module, for example).
If the design and verification teams each have their own "common_pkg" package, is it possible to somehow compile them both and use design's common_pkg for design and verification's common_pkg for verification?
My idea was to limit their scope by encapsulating them in design/verification packages, like so:
package design_pkg;
package common_pkg;
typedef enum {<something>} my_type;
endpackage : common_pkg
endpackage : design_pkg
package verification_pkg;
package common_pkg;
typedef enum {<something_else>} my_type;
endpackage : common_pkg
endpackage : design_pkg
// In design:
design_pkg::common_pkg::my_type my_design_var;
// In verification:
verification_pkg::common_pkg::my_type my_verification_var;
But, it seems that package nesting is illegal in systemverilog, which is strange since module definitions can be nested.
Is there a solution for this problem, other than renaming the packages and avoiding too "broad" names such as "common_pkg" which might conflict with other areas?
Welcome to system verilog :-(. Unfortunately SV does not provide any solution for package name collisions, nor any good way for any other type of naming collisions in global scope.
This is why you might hear the term 'uniquification' from some companies. It really means modifying source code in an automated way to uniquely name global scope items, like packages, modules, macros, ... for verilog building blocks coming from multiple teams (IPs).
So, the best solution is for your teams to talk to each other and agreed on using of names.
Wouldn't it be great if engineering teams could work together and common_pkg really meant a common package common to all?
SystemVerilog has no built-in way of having multiple packages with the same name. Even if you could nest packages, the visibility of the package would be limited to the package it was enclosed in.
Some tools might allow you to compile and optimize the design with its package, and then bind the design unit as a whole.
This issue is a pure design modeling
I have two packages and there are different classes with same name should embedded to these packages
what's the good design solution if I have same classes in different packages
I have read different solutions based on coding such as:
1-use "import"dependency between packages to avoid redundancy classes
2-create instance of classes in other package, and thus allow to have same name classes in different packages
3-fully qualify one of the class name
Would you suggest which is best solution or tell me other good solutions please?
You are allowed to use the same name for classes when they are I different packages. A package is a namespace so the fully qualified names of such classes will be different. Now how you access the class depends on in which package are you at the moment. Whenever you're outside the package containing the class (either directly out through import/access), you have to use fully qualified names to avoid ambiguity.
If the classes are actually the same, you may:
- put it the one package where it suits more and simply access it from the other package (standard approach, possible for all public classes)
- put it in one of the packages (if it suits there better for some reason) and import it to the other package (through element or package import)
- put it in additional package (e.g. Utils) and import it to both packages.
The choice will depend on specific situation.
If it is the same class you should define it in one package and "reuse" it in the other.
A complete UML modeling tool should be able to Drag-n-Drop an existing class in another package.
The tool should be able to indicate you are using a class from another package.
In java, there is a way to import a class and all of its children in one line:
import java.utils.*
In Perl, I've found I can only import specific classes:
use Perl::Utils::Folder;
use Perl::Utils::Classes qw(new run_class);
Is there similar way like java to import everything that falls under a tree structure, only in Perl?
No, there is not a way to easily do what you are after.
You could walk the relevant paths in your PERL library's filesystem and use every .pm file you came across (that's what Module::Find, as suggested by #Daniel Böhmer, does), but that can miss a few things:
Packages that are declared in funny ways/at runtime.
Multiple packages per module file.
Other cases I haven't thought of.
This is also a bad idea, for a few reasons:
You mentioned "classes" in your question, rather than just packages. Perl packages and subpackages do not necessarily represent classes/instantiable object-oriented code. If you were to programmatically generate a list of all packages in a hierarchy and then call $packagename->new() on each of them, you might have a syntax error, if one of the packages was just a library of functions.
Packages and subpackages often are not directly related, developed by the same people, or used for similar things. Just because a package starts with Net:: doesn't mean that it will obey standard conventions that other Net::-prefixed packages expect. For example, File::Find and File::Tail share a prefix, but have very little to do with each other; the prefix is in common because both utilities work with files as their goal.
Lots of packages do things at BEGIN/INIT/etc time when they're compiled. Some of them (sadly) do different things depending on the order in which they're used relative to other modules. The solution to this problem for module developers is "don't do that", but for module users, it's "use sparingly, and only when needed".
It clutters your local namespace with lots of potentially-exported symbols you don't necessarily need (to conditionally import symbols, you'll have to use import arguments like you're doing in your example; there's no programmatic way to define "symbols I'm interested in", since Perl doesn't have that kind static analysis at compile time . . . not for lots of call styles, at least).
It slows down your program's startup time by compiling things you might not necessarily need. This might not seem important at the early phase of a project, but for larger projects it is very easy to end up in situations where you're pulling in over a thousand CPAN modules when you start Apache (or launch your main script, or whatever), and your app takes more than a minute just to start.
I have a hunch that you're trying to reduce boilerplate (as in: all of your modules have a big block of use statements at the top, and that's duplicated everywhere). There are a few ways to do this, starting with:
Don't: import things in each module as you need them, and use strict/warnings and lots of tests to be told early on if you're calling functionality that you haven't imported yet.
You could also make your own Exporter subclass that uses all of your standard modules and adds the functions that you frequently use from them to its #EXPORTS (or splices their #EXPORTS onto its own, or uses Exporter sub-sub-classing, or something).
Factor your code so that the parts that depend on multiple imported modules live in a single utility module, and import that.
Factor your code so that the parts that depend on the imported modules live in a parent class, and address its methods via instances of subclasses (or SUPER), so your subclasses don't have to explicitly contain the imports, e.g. $instance->method_that_calls_an_imported_function_in_the_parent();
Also, as an aside, using package.* imports in Java is debatable, and has many of the same drawbacks of doing it in Perl.
In Perl, the class Foo::Bar::Foo may not be a subclass of Foo::Bar. Nor, is there any guarantee that a subclass module even has the same class prefix. IO::File is a subclass of IO::Handle and not of IO which isn't even a module.
There also isn't even an easy way to tell of a Perl module is a sub-class of another Perl module. There are (at least) three ways to declare a subclass' relationship to a class:
use parent
use base
The #ISA package variable
It is possible to use #INC to find all modules, then look at the source and look at use parent, use base, and #ISA declarations and build a Perl class matrix, then go through that matrix to load the classes you do need. That will probably be slow and cumbersome, and doesn't even cover Moose based classes.
You're asking the wrong question. You're asking "Find all of the subclasses of a particular class.". This will include classes that you're probably not even interested in. I know (for example LWP) that there can be dozens of various classes and subclasses that include stuff you're not even interested in.
What you should be asking is "What do I need to do?", and then find the classes that fulfill your needs. If these classes happen to be child classes of a particular parent class, these subclasses will load the required class.
We do Java programming here, and one of the standards is not to use asterisks in our import statements. This is considered sloppy programming. If you need a particular class, you should declare it rather than simply declaring a superclass. Many of our reporting tools have problems with asterisk declarations in import statements.
There is a Module::Find module, but I am not sure exactly how it works. I believe it simply assumes that subclasses are in the same module hierarchy as the superclass, but that's far from true in Perl.
In general, I think it is a bad idea to load a whole 'tree' of modules (or subclasses so to speak).
There is definitely something wrong in your design if you need to know all and everything about sub classes/modules. You break the rules of encapsulation and you should not need to know how a class handles its responsibilities.
I have created some of my own user packages and have run into a name clash.
In Java, the naming convention is to use your domain name in the package name:
e.g. import com.example.somepackage;.
Are there any widely used package naming conventions for common lisp packages?
Regards,
Russell
The convention I use is to use a unique word: salza, skippy, zs3, etc. I don't really try to have a direct relationship to the library functionality. I try to avoid generic words that others might use like "zlib" or "zip" or "png".
Edi Weitz uses Frank Zappa-related words to name many of his packages: Hunchentoot, Drakma, etc.
Some people use Java-style org.foo.bar reversed domain naming.
So, the direct answer is no, there isn't a common, agreed-upon convention that everyone uses.
One convention that you see sometimes is packages which provide a thin compatibility wrapper over routinely implemented but non-standardized functionality are often called TRIVIAL-SOMETHING.
This leads to some really wonderful names: the library for working with *FEATURES* in a implementation-independent way is called TRIVIAL-FEATURES; even better, the library for interacting with the garbage collector in a standardized way is called TRIVIAL-GARBAGE.
There's no general convention, but there are a few patterns:
When the library is a port from some other language, a wrapper or an interface library it is often prefixed with cl-, like cl-gtk2 or cl-ppcre. Although there was a time, when this prefix got abused, and there are a lot of packages (e.g. cl-who), that implement a unique functionality, but still use it.
If the package is implementation-specific, it's prefixed with implementation shorthand (most notably: sb-), like sb-queue or lw-compat.
If the package is a compatibility layer between implementations, it is often prefixed with trivial-, like trivial-backtrace or trivial-garbage
There's also s- prefix, which may stand for 'symbolic', like s-xml, but it's rarely used.
These prefixes help making the name of the package unique and thus simplify finding information about it on the web.
Otherwise there are no specific conventions, but the general rule is to favor short, unique and, probably, descriptive names. For the reasons of ease of remembering, usage and finding information.
If the package happens to have a long name it's handy to provide a shorter nickname, because more often, than not people will use package's symbols qualified by their names. For example in my code I add a nickname re to cl-ppcre, and it makes the client code much more understandable and clear. Although caution should be applied, so that nicknames didn't cause name-conflicts.