Page 1 of 2
[Request] Module Export
Posted: 17 Oct 2018, 08:29
by Chunjee
Hello,
I am officially requesting Moduled Exports in the likeness of Node.js:
https://nodejs.org/api/modules.html
It would be nice to be able to use external functions without following the naming convention the function creator chose.
Psuedocode:
Code: Select all
Class exampleClass{
__New() {
}
exampleMethod(parameter) {
;do something
}
Export(exampleClass)
Code: Select all
exampleFunction(parameter1, parameter2) {
;do something
}
Export(exampleFunction)
Code: Select all
Import(module.ahk)
myclassinstance := new exampleClass()
mynamedfunction := Import(function.ahk)
mynamedfunction("foo","bar")
#import %filename% as %varname% also a good suggestion.
As a note, its easy in javascript as everything including functions can be saved as objects and transported elsewhere:
Code: Select all
function myCoolFunction() {
// do something
}
module.exports = {
myCoolFunction: myCoolFunction
};
Code: Select all
var myCoolFunctionInstance = require('myCoolFunction');
// searches recursively in parent directory for myCoolFunction library and imports as user specified object.
myCoolFunctionInstance.doSomething()
In addition: I have been working around the outdated way AHK sources code from other files, but increasingly I am coming up against an issue where the same function cannot be defined twice:
Known limitation: Currently, the name of each subroutine (label) must be unique among those of the entire script. The program will notify you upon launch if there are duplicate labels.
This turns into an issue when for example two libraries share a dependency on a third library. In the theoretic circumstance where all libraries are updated and not conflicting, you still have not solved for situations where a library requires an older version of a library (difference in argument order, accepted types, etc)
Notes and links:
https://autohotkey.com/docs/Functions.htm#lib
Re: Module Export
Posted: 17 Oct 2018, 08:37
by nnnik
#import %filename% as %varname% would be my prefered syntax for this.
All files loaded like this receive their own scope and settings.
They also receive their own A_Variables and functions.
In this syntax the person creating the library does not need to care about the way it is imported and we can keep the current libraries unchanged.
Re: [Request] Module Export
Posted: 18 Oct 2018, 18:38
by kczx3
Re: [Request] Module Export
Posted: 18 Dec 2018, 15:23
by Chunjee
https://autohotkey.com/docs/commands/_Include.htm
#IncludeAgain allows multiple inclusions of the same file, while being the same as #Include in all other respects.
I'll see if this can be leveraged in any way.
Re: [Request] Module Export
Posted: 18 Dec 2018, 16:48
by kczx3
Can you explain how that may be helpful?
Re: [Request] Module Export
Posted: 19 Dec 2018, 15:25
by Chunjee
For some reason, I thought it would allow multiple a the same function to be defined more than once but I was wrong.
Re: [Request] Module Export
Posted: 15 Feb 2019, 03:01
by coffee
This *may* be emulated using AutoHotkey_H (latest version, v2) if you want to experiment. You can try asking HotkeyIt for some help with this. He can probably iron out any quirks to make it work 'neatly', if you propose something.
Raw proof of concept:
For a file called "namedModule.ahk"
Code: Select all
exports.world := func("world")
exports.xvar := "holy canoli"
world()
{
msgbox("inside")
}
It could be "required" as
Code: Select all
mymod := require("namedModule")
mymod.world()
msgbox(mymod.xvar)
;/////////////////// REQUIRE
require(mod)
{
static CRLF := "`r`n"
local obj := CriticalObject()
local script := FileRead(mod . ".ahk")
script := (
"#persistent" CRLF
"exports := CriticalObject(" (&obj) ")" CRLF
script
)
ThreadObj(script).ExitApp()
return obj
}
That example is working in my setup, albeit finicky.
I'm unaware of memory leaks, or performance ramifications, since I literally just sprung this up and I don't really use the multithreading features of autohotkey_h that much.
Re: [Request] Module Export
Posted: 15 Feb 2019, 10:56
by kczx3
What do you mean by finicky?
Re: [Request] Module Export
Posted: 16 Feb 2019, 00:29
by coffee
kczx3 wrote: ↑15 Feb 2019, 10:56
What do you mean by finicky?
If you look at it wrong it throws an access violation.
Doing
msgbox(type(mymod.world)) above the
mymod.world() call in previous post either hangs, throws access violation or works, or all three at the same time ¯\_(ツ)_/¯
Using ahkthread seems more consistent, though I don't know if resources are released automatically. Doing .ahkterminate() throws access violation. Maybe someone who uses autohotkey_h a lot and its variety of ways of creating threads can get it to work for their use.
Code: Select all
world()
{
global glob
msgbox(glob " | " superglob)
}
glob := "global"
global superglob := "superglobal"
class test {
method1()
{
msgbox("method1")
}
}
exports.world := func("world")
exports.xvar := "holy canoli"
exports.classify := test
Code: Select all
mymod := require("namedmodule")
; msgbox(type(mymod.world))
mymod.world()
mymod.classify.method1()
msgbox(mymod.xvar)
;/////////////////// REQUIRE
require(mod)
{
static CRLF := "`r`n"
local obj := CriticalObject()
script := (
"#persistent" CRLF
"exports := CriticalObject(" (&obj) ")" CRLF
"#include " mod ".ahk"
)
; ThreadObj(script).ExitApp()
AhkThread(script)
return obj
}
Re: [Request] Module Export
Posted: 17 Feb 2019, 10:59
by Chunjee
Thanks I'll take a look at that.
Re: [Request] Module Export
Posted: 20 Jan 2020, 10:25
by Chunjee
This request is still open. I guess #Include just works on the global namespace so there's really no clean way to build classes that depend on classes or functions because any change at the global namespace will screw them up.
Re: [Request] Module Export
Posted: 20 Jan 2020, 11:43
by swagfag
i dont think this is gonna be needed if namespaces were to be introduced
there was a fully working PR by @Helgef that just festers nowadays..
Re: [Request] Module Export
Posted: 21 Jan 2020, 08:01
by nnnik
I think Helgefs concept of namespaces was overly bloated and complex.
Though it definitively would work.
Re: [Request] Module Export
Posted: 21 Jan 2020, 08:31
by kczx3
nnnik wrote: ↑21 Jan 2020, 08:01
I think Helgefs concept of namespaces was overly bloated and complex.
Though it definitively would work.
It is certainly a complicated issue to solve due to the very global nature of many of AHKs settings
Re: [Request] Module Export
Posted: 21 Jan 2020, 10:49
by Helgef
Bloated and complex, perhaps in regards to the implementation, but usage is very simple and offers powerful possibilities, imo. However, I did start to rewrite it just a few days ago, I will make the implementation simpler (I hope), but usage will be much more limited. Whether I endure the project or not remains to be seen though
.
Cheers.
Re: [Request] Module Export
Posted: 21 Jan 2020, 11:33
by Chunjee
Helgef wrote: ↑21 Jan 2020, 10:49
Bloated and complex, perhaps in regards to the implementation, but usage is very simple and offers powerful possibilities, imo. However, I did start to rewrite it just a few days ago, I will make the implementation simpler (I hope), but usage will be much more limited.
Where do I find this?
Re: [Request] Module Export
Posted: 21 Jan 2020, 12:21
by Helgef
It is for v2, iirc a103. See
#142,
documentation and executables.
Cheers.
Re: [Request] Module Export
Posted: 21 Jan 2020, 16:42
by HotKeyIt
Here is an example for AHK_H v2, CriticalObject is only required if you want to use it in multi-threading environment:
Code: Select all
module:="
(
world(this){
global glob
msgbox(glob " | " superglob)
}
glob := "global"
global superglob := "superglobal"
class test {
method1(){
msgbox("method1")
}
}
exports.DefineMethod("world",func("world"))
exports.xvar := "holy canoli"
exports.classify := test.new()
)"
mymod := require(module)
mymod.world()
mymod.classify.method1()
msgbox(mymod.xvar)
require(module){
thread:=ExeThread("#persistent`nexports := CriticalObject(" (&obj := CriticalObject()) ")`n" module "`nA_IMPORT_FINALIZED:=1") ; to import from string
; thread:=ExeThread("#persistent`nexports := CriticalObject(" (&obj := {}) ")`n#import " module ".ahk`nA_IMPORT_FINALIZED:=1") ; to import a file
While !thread.ahkgetvar("A_IMPORT_FINALIZED")
Sleep 10
return obj
}
Re: [Request] Module Export
Posted: 26 Jun 2020, 12:44
by Chunjee
In case the OP was not clear. This is needed because if you want to make a library that makes use of another library you are likely screwed because ahk doesn't let you #include in a scoped manner and you can't define functions at anything but the global scope.
You also can't define functions with the same name more than once. So if Library A and library B both want to include a CPU() function, there will be an error because it can't be defined twice.
This isn't a big deal for 90% of ahk users who just want some simple scripts but it makes building long term progress a nightmare because you cannot build on the effort of other libraries and tools without re-writing each library not to conflict or worse, writing everything your library needs to do on it's own. We are familiar with the meaning of
"standing on the shoulders of giants" but it is difficult to make use of giant's shoulders when ahk doesn't make it easy to for giants to congregate. Meaning sure you can #include libraries in your script. But what if that library wants to #inlcude things? It becomes hard to stack libraries because of conflicts and flat scope restrictions, as well as inflexible naming of included libraries, etc.
GeekDude wrote:I like AHK because I have to build everything from scratch every time
Re: [Request] Module Export
Posted: 26 Jun 2020, 12:55
by Helgef
This isn't a big deal for 90% of ahk users who just want some simple scripts
Many more scripts could be simple if there were many good, non-conflicting libraries available
.
But helgef, there are many good non-conflicting libraries! Sure, but maybe there would be more if some developers didn't feel that writing such libraries was a
nightmare because you cannot build on the effort of other libraries and tools without re-writing each library not to conflict and bring everything it needs to the table on it's own.
Anyways, I made another attempt at this
#162.
Cheers.