Usually I create a "Scala Object" that keeps all my global constants.
I have been told that it is better to use "package object" in order to keep constants.
I have never used "package object" previously so my questions are:
What are the best practices to hold constants in Scala and why?
Why do I need "package object"?
You dont need a package object.
However it allows you to make code available at the package level without declaring another class or object.
It's a convenience.
package foo.bar
package object dem {
// things here will be available in `foo.bar` package and all subpackages
// without the need of an import statement.
}
The only convention specified for constants are regarding casing. Constants should be PascalCased
Keep in mind that declaring constants in the package object might make them available in places where you don't want them to be available.
I leave you the naming convention for package objects:
The standard naming convention is to place the definition above in a file named package.scala that's located in the directory corresponding to package pp.
Related
I want to build up a tests library and keep it separated from the libraries under development. My first thought is to go for a structure like the following:
PensLib
--Variants
----BallPoint
----FountainPen
----Tests
------TB_BallPoint
HammocksLib
--Variants
----SingleHammock
----DoubleHammock
----Tests
------TB_DoubleHammock
--Systems
----IndoorWalls
----OutdoorWallAndTree
----CoconutPalms
----Tests
------TB_IndoorWalls
Tests
--PensLib
----Variants
------Test_BallPoint // extends PensLib.Variants.Tests.TB_BallPoint
--HammocksLib
----Variants
------Test_DoubleHammock // extends HammocksLib.Variants.Tests.TB_DoubleHammock
----Systems
------Test_IndoorWalls // extends HammocksLib.Systems.Tests.TB_IndoorWalls
For now let's assume that the way I structure my libraries make sense (which most likely doesn't). I will soon ask more questions on good practices in setting up the testing environment in Dymola and with the Testing Library.
My question is about the correct way to handle relative and absolute paths within models, if possible at all.
The model PensLib.Variants.Tests.TB_BallPoint is used for developing the variant BallPoint
The model Tests.PensLib.Variants.Tests_BallPoint is used for automated testing
I want the model Test_BallPoint to extend the model TB_BallPoint, but I cannot link them. I guess the absolute path PensLib.Variants.Tests.TB_BallPoint is treated as a relative one, since PensLib is found "on the way out" of the Tests library, and from there it goes looking for the rest of the path. Is there perhaps a way to control the path, kind of ..\..\..\PensLib\Variants\Tests\TB_BallPoint?
As you already noted such a setup makes troubles. There are ways around that, namely global name lookup and imports, which I explain briefly further below.
Both solutions are nice when you have such a case in a few situations. But if you have to use it all the time, you make your setup unnecessarily complicated.
Hence, I suggest to make yourself the live easier and change your package structure:
Either create a dedicated test library for every library, maybe PensLib_Tests and HammocksLib_Tests
Or rename the packages in the Tests library and don't use the exact library names
Global name lookup
You can use absolute class paths. They are denoted with a leading ., so this should work:
extends .PensLib.Variants.Tests.TB_BallPoint;
See Modelica Specification chapter 5: Scoping, Name Lookup, and Flattening for details, especially 5.3.3 Global Name Lookup
Importing
You can simply import the library. Lookup of imports is always performed globally.
import PensLib;
extends PensLib.Variants.Tests.TB_BallPoint;
In Java I used to put classes inside packages with long informative names by template domain.company.project.module.ets and used to names like:
ch.qos.logback.classic.net
org.hibernate.cache
com.google.common.collect
But in the sources of akka and sbt projects there are a lot of classes inside packages with simple names:
akka.actor
sbt
And that's not all. There are many classes inside classes. And by classes I also mean objects and traits in all possible combinations. There are object inside traits, traits inside classes, etc. But the level of nesting is always 1 (or should I say 2?).
Obviously, there is another approach to class organization. I wonder if you can give me a tip of how to name packages in scala and when to put classes inside each other?
Hi I will reccomend you to read chater seven of scala for the imatient is free available here: http://typesafe.com/resources/free-books.
As a summary the keypoints, as sayed in the book:
- Packages nest just like inner classes.
- Package paths are not absolute.
- A chain x.y.z in a package clause leaves the intermediate packages x and x.y invisible.
- Package statements without braces at the top of the file extend to the entire file.
- A package object can hold functions and variables.
- Import statements can import packages, classes, and objects.
- Import statements can be anywhere.
- Import statements can rename and hide members.
- java.lang, scala, and Predef are always imported.
I'm a relative newbie to SystemVerilog.
I have a package with class A defined in it. This class uses a virtual interface, since
it's a driver (BFM) in a testbench. I'm using a package so I can use the same BFM in
other designs.
In my testbench, I import the A class and pass to it an instance of the virtual interface.
However, when a task in the class tries to assign a value to a signal in the interface, I'm getting a compilation error.
What am I doing wrong?
How can one package a BFM with a virtual interface?
Thanks,
Ran
SystemVerilog packages cannot include interfaces within the actual package. So your interface needs to be compiled along with you package source. The classes you define will reside in the package while the interface definition resides in the global scope where modules live.
Classes within packages can make references to virtual interfaces, but you need to make sure the interface is compiled and visible, apart from the package source.
Strictly according to the spec, I don't think this is possible since it adds an implicit external dependency:
Items within packages are generally type definitions, tasks, and
functions. Items within packages shall not have hierarchical
references to identifiers except those created within the package or
made visible by import of another package. A package shall not refer
to items defined in the compilation unit scope.
It doesn't say anything about the design element namespace, which is where interface declarations live, but accessing any member of an interface requires a hierarchical reference.
You should consider packages to be completely self-contained, other than pre-processor directives and import.
Generally the class declaration not present before its usage is resolved with the help of systemverilog typedef definition. For example "Class A uses Class B" and "Class B uses class A" then typedef is used to resolve the stalemate.
Now when you bring in the package with the above scenario then one needs to ensure both Class A and Class B have to be in same package. If they are not then the compile wont go through.
The reason being the SystemVerilog parser will need the definition of the classes indicated with the typedef at the end of the package parsing. This fails.
This issue needs to watched out that "typedef does not apply across package".
So I understand that the special UNIVERSAL class is to be considered the base class from which all other objects are created. So if a specific method is not found after Perl traverses the inheritance hierarchy, it will look in the UNIVERSAL class to see if the method can be found there. However, when you create a distribution, no UNIVERSAL.pm package is created. Also, the UNIVERSAL methods 'DOES' and 'can' already exist without a UNIVERSAL.pm... As such, I am not sure if I should be writing UNIVERSAL methods into random packages like so:
sub UNIVERSAL::nicemethod{
launch_teh_missles();
}
Or should I be creating a separate UNIVERSAL package and .pm file? What is considered best practice?
You can add new methods to UNIVERSAL the same way as to any other package:
package
UNIVERSAL; # Line break to fool CPAN indexer
sub nice_method {
...
}
I have a directory with some helper functions that should be put into a package. Step one is obviously naming the directory something like +mypackage\ so I can call functions with mypackage.somefunction. The problem is, some functions depend on one another, and apparently MATLAB requires package functions to call functions in the very same package still by explicitly stating the package name, so I'd have to rewrite all function calls. Even worse, should I decide to rename the package, all function calls would have to be rewritten as well. These functions don't even work correctly anymore when I cd into the directory as soon as its name starts with a +.
Is there an easier solution than rewriting a lot? Or at least something self-referential like import this.* to facilitate future package renaming?
edit I noticed the same goes for classes and static methods, which is why I put the self-referential part into this separate question.
In truth, I don't know that you should really be renaming your packages often. It seems to me that the whole idea behind a package in MATLAB is to organize a set of related functions and classes into a single collection that you could easily use or distribute as a "toolbox" without having to worry about name collisions.
As such, placing functions and classes into packages is like a final step that you perform to make a nice polished collection of tools, so you really shouldn't have much reason to rename your packages. Furthermore, you should only have to go through once prepending the package name to package function calls.
... (pausing to think if what I'm about to suggest is a good idea ;) ) ...
However, if you really want to avoid having to go through your package and prepend your function calls with a new package name, one approach would be to use the function mfilename to get the full file path for the currently running package function, parse the path string to find the parent package directories (which start with "+"), then pass the result to the import function to import the parent packages. You could even place these steps in a separate function packagename (requiring that you also use the function evalin):
function name = packagename
% Get full path of calling function:
callerPath = evalin('caller', 'mfilename(''fullpath'')');
% Parse the path string to get package directories:
name = regexp(callerPath, '\+(\w)+', 'tokens');
% Format the output:
name = strcat([name{:}], [repmat({'.'}, 1, numel(name)-1) {''}]);
name = [name{:}];
end
And you could then place this at the very beginning of your package functions to automatically have them include their parent package namespace:
import([packagename '.*']);
Is this a good idea? Well, I'm not sure what the computational impacts will be if you're doing this every time you call a package function. Also, if you have packages nested within packages you will get output from packagename that looks like this:
'mainpack.subpack.subsubpack'
And the call to import will only include the immediate parent package subsubpack. If you also want to include the other parent packages, you would have to sequentially remove the last package from the above string and import the remainder of the string.
In short, this isn't a very clean solution, but it is possible to make your package a little easier to rename in this way. However, I would still suggest that it's better to view the creation of a package as a final step in the process of creating a core set of tools, in which case renaming should be an unlikely scenario and prepending package function calls with the package name would only have to be done once.
I have been exploring answers to the same question and I have found that combining package with private folders can allow most or all of the code to be used without modification.
Say you have
+mypackage\intfc1.m
+mypackage\intfc2.m
+mypackage\private\foo1.m
+mypackage\private\foo2.m
+mypackage\private\foo3.m
Then from intfc1, foo1, foo2, and foo3 are all reachable without any package qualifiers or import statements, and foo1, foo2, and foo3 can also call each other without any package qualifiers or import statements. If foo1, foo2, or foo3 needs to call intfc1 or intfc2, then that needs qualification as mypackage.intfc1 or an import statement.
In the case that you have a large set of mutually interdependent functions and a small number of entry points, this reduces the burden of adding qualifiers or import statements.
To go even further, you could create new wrapper functions at the package level with the same name as private functions
+mypackage\foo1.m <--- new interface layer wraps private foo1
+mypackage\private\foo1.m <--- original function
where for example +mypackage\foo1.m might be:
function answer = foo1(some_parameter)
answer = foo1(some_parameter); % calls private function, not itself
end
This way, unlike the intfc1 example above, all the private code can run without modification. In particular there is no need for package qualifiers when calling any other function, regardless of whether it is exposed by a wrapper at the package level.
With this configuration, all functions including the package-level wrappers are oblivious of the package name, so renaming the package is nothing more than renaming the folder.