How do you namespace a Dart class? - namespaces

How do you create a namespace for a Dart class? I come from a C# background, where one would just use namespace SampleNamespace { }.
How do you achieve the same in Dart?

Dart doesn't have the concept of namespaces, but instead it has libraries. You can consider a library to be sort of equivalent to a namespace, in that a library can be made of multiple files, and contain multiple classes and functions.
Privacy in Dart is also at the library, rather than the class level (anything prefixed with an underscore is private to that library).
An example of defining a library (using the example of a utilities library:
// utilities.dart
library utilities; // being the first statement in the library file
You can make other files part of the same library by using the part keyword. Part files are only used to help organize your code; you can put all your classes in a single library file, or split them among several part files (or part files and the library file) - it has no effect on the execution. It is stylistic to put the main library file in a parent folder, and part files in a src/ folder.
Expanding the example to show Part files.
// utilities.dart
library utilities;
part "src/string_utils.dart";
part "src/date_utils.dart";
Those part files then link back to the library they are part of by using the part of statement:
// src/string_utils.dart
part of utilities;
// functions and classes
String reverseString(s) => // implementation ....
String _stringBuilder(strings) => // a private (to the library) function,
// indicated by the leading underscore
//... snip other classes and functions
Now that you have a library containing a function, you can make use of that library elsewhere by importing the library:
// my_app.dart;
import "path/to/library/utilities.dart";
main() {
var reversed = reverseString("Foo");
// _stringBulider(["a","b"]); // won't work - this function is
// only visible inside the library
}
If you want to alias your library to avoid clashes (where you might import two libraries, both containing a reverseString() function, you use the as keyword:
// my_app.dart;
import "path/to/library/utilities.dart";
import "some/other/utilities.dart" as your_utils;
main() {
var reversed = reverseString("Foo");
var your_reversed_string = your_utils.reverseString("Bar");
}
The import statement also makes use of packages, as imported by pub, Dart's package manager, so you can also host your library on github or elsewhere, and reference your library as so:
// my_app.dart;
import "package:utilities/utilities.dart";
main() {
var reversed = reverseString("Foo");
}
The pub dependency is defined in a pubspec.yaml file, which tells pub where to find the library. You can find out more at pub.dartlang.org
It is important to note that only the library file can:
contain import statements. Part files cannot.
contain the library keyword. Part files cannot.
contain part files. Part files cannot.
One final point is that a runnable app file can (and is likely to be) a library file, and can also be made of part files
// my_app.dart;
library my_app;
import "package:utilities/utilities.dart";
part "src/edit_ui.dart";
part "src/list_ui.dart";
part "src/foo.dart";
main() {
var reversed = reverseString("Foo");
showEditUi(); // perhaps defined in edit_ui.dart....?
}

The easiest way that I've found to create a namespace in Dart is this:
Say you have the files a.dart and b.dart containing the classes Apple and Banana respectively. Create a file called my_namespace.dart. In this example, it's residing in the same folder as the other two files. Export all the files that you want under your namespace from the my_namespace.dart file:
export 'a.dart';
export 'b.dart';
Then wherever you would like to use the exported code from these two files, use this:
import 'my_namespace.dart' as my_namespace;
// you can now access the classes under the same namespace:
final myApple = my_namespace.Apple();
final myBanana = my_namespace.Banana();
Another way to do this, which removes the need of the intermediary file my_namespace.dart, is to have several import statements with the same alias:
import 'a.dart' as my_namespace;
import 'b.dart' as my_namespace;
// you can once again access the classes under the same namespace:
final myApple = my_namespace.Apple();
final myBanana = my_namespace.Banana();
I prefer the first method because I don't have to repeat the multiple import statements whenever I need to use a class under the namespace.
Of course the imported and exported files do not need to be in the same folder, but having the files under the same namespace in the same folder would probably be more convenient.

Related

How do I import the Three.js Line library as an ES6 module?

I do my development using modern JS (ES6) which means modules.
Although Three.js is available as an ES6 module. The line library - LineSegmentsGeometry, LineGeometry, LineSegments2, etc. - is not.
What are my options here?
You have a couple options.
First and foremost, edit the code.
You're welcome to modify the code, and so you could manually turn it into an ES6 module. You would want to remove any references of THREE, and export anything that was normally attached to that object. You'll also need to import any required core THREE.js components, like Mesh, Vector3, etc.
The way I prefer to do this is to copy the file I'm updating locally, and change references to it. For example:
// local_three_modules/LineSegments2.js
import { Mesh, Vector3, etc. } from "three"
let LineSegments2 = function ( geometry, material ) {
// ...
}
export default LineSegments2
// app.js
import { Mesh, Vector3, etc. } from "three"
import LineSegments2 from "./local_three_overrides/LineSegments2.js"
// and so on...
Your other option is to use a bundler with an export loader.
Webpack (and other bundlers, I'm just more familiar with Webpack) provides a exports-loader which can be used against specific files that don't export anything. For example, you can tell the exports-loader to export THREE from LineSegments2.js. To get webpack involved in this process, you need to tell it to use the loader on the file. You can do this through the webpack configuration, or inline in the code like this:
import THREE from "exports-loader?THREE!./node_modules/three/examples/js/lines/LineSegments2.js"

Does SystemVerilog support global functions?

I want to make a parity_check function which can be accessed by three different modules. Is this possible in SV? If yes, where do I declare this function and how do I import it into my module?
You can put a function into a separate file and include it using `include:
`include "some_file_name.sv"
However, a much better way is to use a package:
package some_package_name;
function string some_function_name;
return "some_function_name called";
endfunction
endpackage
You would put that into a separate file and you must compile that before compiling any module that uses it. You then import the package into each module:
module some_module_name;
import some_package_name::*; // or import some_package_name::some_function_name;
initial
$display(some_function_name);
endmodule
Putting a function in a package is better than just putting it into a file and using include, because a package is a named scope. Because a package is a named scope, any issues with some clash of names can be resolved by, instead of using import, referring to the full name of the function in its package, eg:
module some_module_name;
initial
$display(some_package_name::some_function_name);
endmodule

Using ES6 `import` with CSS/HTML files in Meteor project: bug or feature?

I am currently learning Meteor and I found out something that intrigued me.
I can load HTML and CSS assets from a JS file using the import statement.
import '../imports/hello/myapp.html';
import '../imports/hello/myapp.css';
import * as myApp from '../imports/hello/myapp.js';
This was a surprise to me so I ran to google but could not find this behavior documented in the specification for ES6 import or in Meteor's Docs.
So my questions are:
Can I rely on this behavior to build my apps?
Will my app will break when Meteor gets around to fix it -- if it's a bug --?
Notes
I am using Meteor v1.3, not sure if this works also with previous versions.
You can download the app to see this behavior from Github
After going through the implementation of the built files for my app
I found out why this works.
HTML
Files are read from the file system and their contents added to the global Template object, e.g.,
== myapp.html ==
<body>
<h1>Welcome to Meteor!</h1>
{{> hello}}
</body>
results in the following JS code:
Template.body.addContent((function () {
var view = this;
return [
HTML.Raw("<h1>Welcome to Meteor!</h1>\n\n "),
Spacebars.include(view.lookupTemplate("hello"))
];
}));
Which is wrapped in a function with the name of the file as it's key:
"myapp.html": function (require, exports, module) {
Template.body.addContent((function () {
var view = this;
return [
HTML.Raw("<h1>Welcome to Meteor!</h1>\n\n "),
Spacebars.include(view.lookupTemplate("hello"))];
}));
Meteor.startup(Template.body.renderToDocument);
Template.__checkName("hello");
Template["hello"] = new Template("Template.hello", (
function () {
var view = this;
return [
HTML.Raw("<button>Click Me</button>\n "),
HTML.P("You've pressed the button ",
Blaze.View("lookup:counter",
function () {
return Spacebars.mustache(view.lookup("counter"));
}), " times.")
];
}));
},
So all of our HTML is now pure JS code which will be included by using require like any other module.
CSS
The files are also read from the file system and their contents are embedded also in JS functions, e.g.
== myapp.css ==
/* CSS declarations go here */
body {
background-color: lightblue;
}
Gets transformed into:
"myapp.css": ["meteor/modules", function (require, exports, module) {
module.exports = require("meteor/modules").addStyles("/* CSS declarations go here */\n\nbody {\n background-color: lightblue;\n}\n");
}]
So all of our CSS is also now a JS module that's again imported later on by using require.
Conclusion
All files are in one way or another converted to JS modules that follow similar rules for inclusion as AMD/CommonJS modules.
They will be included/bundled if another module refers to them. And since all of them are transformed to JS code
there's no magic behind the deceitful syntax:
import '../imports/hello/myapp.html';
import '../imports/hello/myapp.css';
They both are transpiled to their equivalent forms with require once the assets have been transformed to JS modules.
Whereas the approach of placing static assets in the imports directory is not mentioned in the official documentation,
this way of importing static assets works.
This seems to be at the core of how Meteor works so I'd bet this functionality is going to be there for a long while.
I don't know if to call this a feature maybe a more appropriate description is unexpected consequence but that would
only be true from the user's perspective, I assume the people who wrote the code understood this would happen and perhaps even
designed it purposely this way.
One of the features in Meteor 1.3 is lazy-loading where you place your files in the /imports folder and will not be evaluated eagerly.
Quote from Meteor Guide:
To fully use the module system and ensure that our code only runs when
we ask it to, we recommend that all of your application code should be
placed inside the imports/ directory. This means that the Meteor build
system will only bundle and include that file if it is referenced from
another file using an import.
So you can lazy load your css files by importing them from the /imports folder. I would say it's a feature.
ES6 export and import functionally are available in Meteor 1.3. You should not be importing HTML and CSS files if you are using Blaze, the current default templating enginge. The import/export functionality is there, but you may be using the wrong approach for building your views.

Problems with compiling multiple AS3 packages w/ant and mxmlc

I'm trying to extend the BigBlueButton client with some proprietary classes. Specifically the phone module, where I added a file with my own code. When I write my own package name (org.mydomain.module.test ...) within the file, the compiler fails because it can't find my class from the mxml file. But when I use the original package name (org.bigbluebutton.module.phone ...) it compiles fine. Obviously when I use a different package name, the file is not included in the compilation. How can I change this?
This fails:package org.mydomain.module.test
{
public class MyTestClass
{
// code here
}
}
But this works:package org.bigbluebutton.modules.phone.test
{
public class MyTestClass
{
// code here
}
}
FYI: BigBlueButton uses ant to compile the client.
You didn't say where you put the files on disk, the package name should match the file's path in your project. Is that the case in both examples?
So when the package name is: org.mydomain.module.test
The class file should be saved in the path:
my_project_path/src/org/mydomain/module/test

Checkstyle check for duplicate classes

The project I am on is having horrible problems with class collisions in the classpath and developers reusing class names. For example, we have 16, yes 16 interfaces called Constants in this bloody thing and its causing all kinds of problems.
I want to implement a checkstyle check that will search for various forms of class duplication. here's the class
import java.io.File;
import java.util.List;
import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
import com.wps.codetools.common.classpath.ClassScanner;
import com.wps.codetools.common.classpath.criteria.ClassNameCriteria;
import com.wps.codetools.common.classpath.locator.ClasspathClassLocator;
/**
* This codestyle check is designed to scan the project for duplicate class names
* This is being done because it is common that if a class name matches a class
* name that is in a library, the two can be confused. Its in my best practice that
* the class names should be unique to the project.
*
*
*/
public class DuplicateClassNames extends AbstractFileSetCheck {
private int fileCount;
#Override
public void beginProcessing(String aCharset) {
super.beginProcessing(aCharset);
// reset the file count
this.fileCount = 0;
}
#Override
public void processFiltered(File file, List<String> aLines) {
this.fileCount++;
System.out.println(file.getPath());
ClassScanner scanner = new ClassScanner();
scanner.addClassCriteria(new ClassNameCriteria(file.getPath()));
scanner.addClassLocater(new ClasspathClassLocator());
List<Class<?>> classes = scanner.findClasses();
if (classes.size() > 0) {
// log the message
log(0, "wps.duplicate.class.name", classes.size(), classes);
// you can call log() multiple times to flag multiple
// errors in the same file
}
}
}
Ok, so the ClassScanner opens up the classpath of the current JVM and searches it with various criteria. This particular one is a class name. It can go into the source folders, and most importantly it can go into the libraries contained in the classpath and search the *.class files within the jar using ASM. If it finds copies based on the criteria objects that are presented, it returns an array of the files. This still needs some massaging before mainstream but im on a time budget here so quick and dirty it goes.
My problem is understanding the input parameters for the check itself. I copied from the example, but it looks like CheckStyles is giving me a basic IO file object for the source file itself, and the contents of the source file in a string array.
Do I have to run this array thru another processor before I can get the fully qualified class name?
This is more difficult to do right than one might think, mostly because Java supports all kinds of nesting, like static classes defined within an interface, anonymous inner classes, and so on. Also, you are extending AbstractFileSetCheck, which is not a TreeWalker module, so you don't get an AST. If you want an AST, extend Check instead.
Since "quick and dirty" is an option for you, you could simply deduce the class name from the file name: Determine the canonical path, remove common directories from the beginning of the String, replace slashes with dots, cut off the file extension, and you are more or less there. (Without supporting inner classes etc. of course.)
A better solution might be to extend Check and register for PACKAGE_DEF, CLASS_DEF, ANNOTATION_DEF, ENUM_DEF, and INTERFACE_DEF. In your check, you maintain a stack of IDENTs found at these locations, which gives you all fully qualified class names in the .java file. (If you want anonymous classes, too, also register for LITERAL_NEW. I believe in your case you don't want those.)
The latter solution would not work well in an IDE like Eclipse, because the Check lifecycle is too short, and you would keep losing the list of fully qualified class names. It will work in a continuous integration system or other form of external run, though. It is important that the static reference to the class list that you're maintaining is retained between check runs. If you need Eclipse support, you would have to add something to your Eclipse plugin that can keep the list (and also the list from previous full builds, persisted somewhere).