How to make typedef type accessible in multiple files? - haxe

typedef has great benefits, but I don't know how to include the same type in multiple files is haxe?
for example I need to use this type in a.hx and b.hx files:
typedef JsonControl = {
var name:String;
var type:String;
var user_answer:String;
var answer:Array<String>;
var htmlID:String;
}
how to do so?

It works like a regular class definition, so preferably you would define a package and save it as a .hx file. Then simply import it where you want to use it.

As another answer states, the rules for how haxe discovers typedefs is identical to how it finds classes.
Type-Named Module Files
The easiest way to share a type between multiple files in Haxe is to create a module named after that type. For example, suppose you are in package x and want to access the type MyType from multiple files. You would create the file x/MyType.hx and place MyType’s definition in x/MyType.hx. This file might look like this:
package x;
typedef MyType = {
id:String,
}
Module Sub-Types
If you want, you may place MyType in a differently-named file such as x/MySharedTypes.hx. If you do that, accessing it takes more work. To consume it in another file, you either need to have an import x.MySharedTypes statement or type the module-qualified name x.MySharedTypes.MyType (from a file in package x, you only need to type MySharedTypes.MyType). In this example, you might have:
x/MySharedTypes.hx:
package x;
typedef MyType = {
id:String,
}
x/MyFirstConsumer.hx:
package x;
import x.MySharedTypes;
class MyFirstConsumer {
var instance:MyType;
}
x/MySecondConsumer.hx:
package x;
class MySecondConsumer {
var instance:MySharedTypes.MyType;
}
Documentation
You may read further details in the page titled Module Sub-Types in the manual.

Related

How does Node.js module system handle modifying and accessing variable of the same module of different versions?

I have a custom Node.js module fooModule that has a private variable foo and public getter and setter to modify this variable.
I have another two modules: zooModule depends on the fooModule#^1.0.1 and cannot use pre-release so far and barModule that depends on the fooModule#^1.0.2-0 (pre-release patch version that contains some fix) and zooModule at the same time.
The barModule firstly sets the foo variable value and then zooModule reads the value of foo.
I have noticed that when the version of the fooModule dependency is the same, then it works as expected, in other words the foo variable is shared between two modules. However, using different versions results in undefined when accessing foo from zooModule.
Here is a small pseudo example to demonstrate the logic. Each of the modules is a standalone npm package.
// fooModule.js
let foo;
export const getFoo = () => foo;
export const setFoo = (newFoo) => foo = newFoo;
// zooModule.js uses v.1.0.1 of the fooModule
import { getFoo } from './fooModule.js'
export const zooFunc = () => {
const zoo = getFoo();
if(!zoo) return;
...
return zoo; //result depends on zoo
};
// barModule.js uses v.1.0.2-0 of the fooModule
import { setFoo } from './fooModule.js'
import { zooFunc } from './zooModule.js'
setFoo('foo');
zooFunc(); // What is the output?
As far as I am concerned, in case of different versions of the fooModule, we become two different instances of the module and accordingly of the variable foo?
I tried to explain the question best I could, but it was hard to explain what I mean, sorry if it is still unclear.
Could give me some hints where to read more about this or give some explanation on how this is supposed to work. Thanks for your time.
EDIT:I forgot to mention that I have this use case in a frontend project bundled by a webpack.

Difference between `import from` and `import require` in TypeScript

I use node.js and I recently decided to give TypeScript a shot, But I'm kinda confused on how modules get imported. I see two different syntax that I couldn't find out what's their difference exactly:
import * as a from 'a'; // ES6 standard to import stuff
// OR ...
import a = require('a');
Are these the same thing? and if they're not, where should I use each one of them?
import * as a from 'a'; is the new "ES6 style" import syntax (available since Typescript 1.5).
Whenever possible, this syntax should now be used.
There is one caveat though. The ES6 import syntax can only import modules (as defined by ES6) or objects (classes, interfaces, vars,... ) exported as part of a module.
Some Javascript librairies will directly export a function or class, and the corresponding definition file will typically look like this:
declare module "my-class" {
class MyClass { ... }
export = MyClass
}
In this case, the "old" import syntax is the only one that can be used
import MyClass = require("my-class");
Failure to use this syntax will result in error TS2497
Check this issue for details and a possible workaround which would be, in the previous case, to add an empty module declaration to the definition file
declare module "my-class" {
class MyClass { ... }
module MyClass {} // <=
export = MyClass
}

How to export symbol from Linux kernel module in this case?

I've got two kernel modules built, one of which is a net_device. My net_device module A depends on module B which provide some extra control mechanism to export device info.
I want module B to be able to call the "xmit" function which is in module A. As a result, module B will become dependent on module A if I simple export symbol from A. This, obviously, creates a "deadlock" dependency situation.
Does anyone have experience resolving this? How can I properly export the "xmit" function in A and let B use it?
You may provide the callback function from module A. In that case you don't need to export each function you need to the kernel namespace. I presume you just could supply some structure to the B. Something like:
internal header:
struct possible_ops {
int (*xmit)(...);
};
A:
struct private {
struct possible_ops *ops;
};
...
ops = kzalloc(sizeof(*ops));
ops->xmit = xmit;
B:
whatever(struct possible_ops *ops) {
if (ops && ops->xmit) {
ret = ops->xmit();
...
}
}

C90 Cast to underlying abstract type

A logging structure that depends on logging related functions looks like this:
typedef struct
{
TFkt_vlogf vlogf;
TFkt_outf outf;
void* logData;
} TLogger;
In this logging function there is an abstract logData that is assigned with different pointers depending on the job that the logger has.
A Filelogger would at one point access a stored filehandle like this.
FILE * fileHandle = (FILE *)(logger->logData);
Although this compiles SPLint is unhappy about this and complains with this message:
Cast to underlying abstract type FILE *: (FILE *)(logger->logData)
What can i do to satisfy SPLint?
i tried to sprinkle some /*#abstract#*/ around but it did not help
Is there a better way in C90 to store and access data while still keeping the structure signature to pass the type around independent of its implementation?
The better Solution is to use a union and have all possible Data inside that union.
typedef union
{
FILE * fileHandle;
char something;
long int other;
} TLog_data;
typedef struct
{
TFkt_vlogf vlogf;
TFkt_outf outf;
TLog_data logData;
} TLogger;
At some point during execution you would use:
((TLogger*) logger)->logData.fileHandle

TypeScript module import in nodejs

What is best practice for importing modules in nodejs with typescript? I come from c# background so I want to do something like this
MyClass.ts
module MyNamespace {
export class MyClass {
}
}
app.ts
// something like using MyNamespace
new MyNamespace.MyClass();
or
MyClass.ts
export class MyClass {
}
app.ts
import MyClass = module("MyClass")
new MyClass();
I know I can do this and it will work, but then I have to think up for two names for each class
import MyClass2 = module("MyClass")
new MyClass2.MyClass();
Point is separating classes to multiple .ts files (preferably one file per class). So question is, how is this done?
You have two choices here:
If you insist on using CommonJS or AMD modules, then you will have to use external modules just the way you described it in your question. Whether or not you use a module to declare your own namespace is mostly a matter of taste. The only way to circumvent the issue of specifying two names is to create a variable that aliases the type:
mymodule.ts
export module MyNamespace {
export class MyClass {
}
}
app.ts
import ns = require('mymodule');
var myclass = new ns.MyNamespace.MyClass();
var myclassalias = ns.MyNamespace.MyClass;
var myclass2 = new myclassalias();
Your other option is to use internal modules which are mostly used to structure your code internally. Internal modules are brought into scope at compile time using reference paths.
mymodule.ts
module MyNamespace {
export class MyClass {
}
}
app.ts
///<reference path='mymodule.ts'/>
var myclass = new MyNamespace.MyClass();
I think you'll have to decide for yourself which of those two approaches is more appropriate.
You can import TypeScript modules into a node.js file using the typescript-require module, which was created for this specific purpose.
I would recommend against using the explicit module (or namespace) keyword, it's a vestigial remnant of an earlier time.* You generally don't need them because any typescript file with a top-level import or export is automatically a module. Your second myModule.ts example was good.
export class MyClass {
...
}
But when you import it to another typescript module, you'll want to use something like this:
import { MyClass } from './myModule';
var myInstance = new MyClass();
Personally, I don't like repetitiveness of line 1, but it is what the language calls for, so I've learned to accept it. I think the utility of this syntax isn't apparent unless you abandon the file-per-class pattern. You pick and choose what names to import from the module, so that no unintended namespace pollution occurs.
An alternative import syntax pulls in all names from the module, but you must qualify the names with the module when you use them. Therefore it is also name collision resistant.
import * as myModule from './myModule';
var myInstance = new myModule.MyClass();
There are exceptions to the general rule about not needing module / namespace keywords, but don't start by focusing on them. Think file == module.

Resources