Passing variables between scripts Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
Hol3yMol3y
Posts: 19
Joined: 10 Jun 2019, 04:08

Passing variables between scripts

30 Jun 2019, 03:55

I need to pass a set of variables from one script to another and I need to do it a few times while both scripts are running.

My current setup writes all variables to a .txt document using FileAppend. Meanwhile, the second script is listening for when the txt document changes.

That's as far as I've gotten. Once it detects the update, I would like it to read the txt document as if it were part of the code.

For instance, the contents of the document look like this:

FirstName := Bob
Surname := Jones
Street := Jones Street

etc.

Now, I could loop through it line by line and parse the contents of it to create a line something like: VariableName " := " %VariableContents%, but this seems silly when it's already in the exact format that I want it in. I really just want to paste the exact contents of the txt doc into my script so that all of the variables are declared at once and I can use them.

This isn't a matter of being lazy either - there could be hundreds of variables in this file and I need the script to work fast.

I tried writing all of the variables to an AHK file and using an #include to bring the file into my second script. Unfortunately I can't find a way to make the #include update when the contents of the target script change (and I can't reload the script either for various reasons). I also looked into .ini files but these don't seem to have any benefit and I don't need the Header functionality.

So, basically my question is this: does anyone know an easy way to make AHK read a txt file of variables and declare them all as written? Alternatively, if it can't be done, can someone help me write a Loop function to parse it line by line?

Cheers!
Odlanir
Posts: 438
Joined: 20 Oct 2016, 08:20

Re: Passing variables between scripts

30 Jun 2019, 04:52

In the OnMessage docs : https://www.autohotkey.com/docs/commands/OnMessage.htm there's a good working example ( the last one ) on how to send/receive data between scripts:
____________________________________________________________________________
Windows 10 Pro 64 bit - Autohotkey v1.1.30.01 64-bit Unicode
Hol3yMol3y
Posts: 19
Joined: 10 Jun 2019, 04:08

Re: Passing variables between scripts

30 Jun 2019, 05:29

If I use this method then I take it I would have to send the variables in one single variable and then parse them on the other end?

This is probably really basic, but when I tried something similar once, I ended up with a horizontal line of code that exceeded some sort of internal limit that AutoHotKey puts in place and the code wouldn't run. How do I avoid that if I use this method?
Hol3yMol3y
Posts: 19
Joined: 10 Jun 2019, 04:08

Re: Passing variables between scripts

30 Jun 2019, 05:39

Also, another point to note - what I'm really trying to achieve is multithreading. I'm passing off a task to a second script so that the user can keep using the first script without it interfering.

I've had a look into some of the more sophisticated ways of doing this like ObjRegisterActive and LoadFile libraries but they're just too advanced for me to understand at this stage.
User avatar
SpeedMaster
Posts: 300
Joined: 12 Nov 2016, 16:09

Re: Passing variables between scripts

30 Jun 2019, 05:58

Hol3yMol3y wrote:
30 Jun 2019, 03:55
So, basically my question is this: does anyone know an easy way to make AHK read a txt file of variables and declare them all as
you can also share the same ini file 8-)
https://autohotkey.com/board/topic/33506-read-ini-file-in-one-go/

I use this function ini( filename = 0, updatemode = 0 ) (by Smurth)
If you want to create lots of variable from .ini files, this function is for you. It reads the whole file in one go and creates all the global variables.

Code: Select all

;https://autohotkey.com/board/topic/33506-read-ini-file-in-one-go/
ini( filename = 0, updatemode = 0 )
;
; updates From/To a whole .ini file
;
; By default the update mode is set to 0 (Read)
; and creates variables like this:
; %Section%%Key% = %value%
;
; You don't have to state the updatemode when reading, just use
;
; update(filename)
;
; The function can be called to write back updated variables to
; the .ini by setting the updatemode to 1, like this:
;
; update(filename, 1)
;
{
Local s, c, p, key, k, write

   if not filename
      filename := SubStr( A_ScriptName, 1, -3 ) . "ini"

   FileRead, s, %filename%

   Loop, Parse, s, `n`r, %A_Space%%A_Tab%
   {
      c := SubStr(A_LoopField, 1, 1)
      if (c="[")
         key := SubStr(A_LoopField, 2, -1)
      else if (c=";")
         continue
      else {
         p := InStr(A_LoopField, "=")
         if p {
         k := SubStr(A_LoopField, 1, p-1)
       if updatemode=0
          %key%%k% := SubStr(A_LoopField, p+1)
       if updatemode=1
       {
          write := %key%%k%
          IniWrite, %write%, %filename%, %key%, %k%    
       }
         }
      }
   }
}
Here is the test file and function in one file together. (by Tuncay and Scratch)

Code: Select all

#SingleInstance force

/*
; ATTENTION! THIS COMMENT BLOCK IS IN INI FORMAT AND COULD BE USED AS INI FILE.
[META]
Source=				http://www.autohotkey.com/forum/viewtopic.php?t=36601
Language=              en
Description=           If you want to create lots of variable from .ini files, this function is for you. It reads the whole file in one go and creates all the global variables. 
Date=                  2009-09-07
Author=                Scratch
Category=              File Management
Type=                  Library
*/

#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%

; .....................................................
;                    TEST SECTION
; .....................................................

; Create the ini file (scriptname.ini)
iniFile := SubStr( A_ScriptName, 1, -3 ) . "ini"
iniContent =
(
[pos]
x=100
y=300
Z=450
)
replaceFile(iniFile, iniContent) ; delete previous ini file and replace it with the new one

;--------------------------------------------
ini(test) ; Read the ini file and store its content to variables
;--------------------------------------------

msgbox posx := %posx% , posy := %posy% , posz := %posz%
;
; Now we change the variables and write/update the ini
;
posx := posx * 2
posy := posy * 2
posz := posz * 2

;--------------------------------------------
ini(test, 1) ; write/update the ini file
;--------------------------------------------

Msgbox Updated variables written...
;
; To confirm the INI is correctly updated, we read out the INI again
;
ini(test)
msgbox UPDATED >>> posx := %posx% , posy := %posy% , posz := %posz%


RETURN ; END OF Auto-execution section


replaceFile(File, Content)
{
	FileDelete, %File%
	FileAppend, %Content%, %File%
}
Return

; .....................................................
;               END OF TEST SECTION
; .....................................................


ini( filename = 0, updatemode = 0 )
;
; updates From/To a whole .ini file
;
; By default the update mode is set to 0 (Read)
; and creates variables like this:
; %Section%%Key% = %value%
;
; You don't have to state the updatemode when reading, just use
;
; update(filename)
;
; The function can be called to write back updated variables to
; the .ini by setting the updatemode to 1, like this:
;
; update(filename, 1)
;
{
Local s, c, p, key, k, write

   if not filename
      filename := SubStr( A_ScriptName, 1, -3 ) . "ini"

   FileRead, s, %filename%

   Loop, Parse, s, `n`r, %A_Space%%A_Tab%
   {
      c := SubStr(A_LoopField, 1, 1)
      if (c="[")
         key := SubStr(A_LoopField, 2, -1)
      else if (c=";")
         continue
      else {
         p := InStr(A_LoopField, "=")
         if p {
         k := SubStr(A_LoopField, 1, p-1)
       if updatemode=0
          %key%%k% := SubStr(A_LoopField, p+1)
       if updatemode=1
       {
          write := %key%%k%
          IniWrite, %write%, %filename%, %key%, %k%    
       }
         }
      }
   }
}
just me
Posts: 6430
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Passing variables between scripts

30 Jun 2019, 07:45

If you want to use a simple text file and create an associative array in the receiving script:
:arrow: by Odlanir
swagfag
Posts: 2765
Joined: 11 Jan 2017, 17:59

Re: Passing variables between scripts

30 Jun 2019, 09:32

if u want to do multithreading, port ur script over to ahk_h and do multithreading. dont come up with the code-equivalent of a convoluted rube goldberg machine held up by nothing but spit and prayers.
there's no getting around not using any of the advanced/sophisticated stuff because the very thing uve set out to do(multithreading/IPC) is itself advanced/sophisticated. u cant just keep on banging away at steel spikes(think railroad ones) with a blowup toy hammer because heavy machinery is too advanced for u... well, u could, technically, but that would be a massive waste of both time and effort on ur part.

that said, i have no idea what the actual thing that ure trying to do is(read: the big picture). first, u say u want to "pass variables from one script to another"(implying one-way IPC). then u say ure actually writing the variables(only?), ahk syntax, in a separate file and u want "to paste the exact contents of the file" into ur worker thread script(paste them where? in the autoexecute section? what if its already been run? are u gonna rerun it? paste them in a function? or perhaps somewhere in between?)
User avatar
SpeedMaster
Posts: 300
Joined: 12 Nov 2016, 16:09

Re: Passing variables between scripts  Topic is solved

30 Jun 2019, 12:26

Hol3yMol3y wrote:
30 Jun 2019, 03:55
So, basically my question is this: does anyone know an easy way to make AHK read a txt file of variables and declare them all as written? Alternatively, if it can't be done, can someone help me write a Loop function to parse it line by line?
If I understand correctly, you want to import the whole stuff ( variable name + content) :shock:
experimental script only !! :roll:

Code: Select all

#SingleInstance forcce
SetWorkingDir, %a_scrpitdir%


; Frist create a test file (test.txt)
fileContent =
(
FirstName := Bob
Surname := Jones
Street := Jones Street
)
replaceFile("test.txt", fileContent)

replaceFile(File, Content)
{
	FileDelete, %File%
	FileAppend, %Content%, %File%
}


; Parse the test file and declare variables
fileread, vars, test.txt

loop, parse, vars, "`n" 
{
	CurrentVar:=strsplit(a_loopfield, "=", ":")
	for k, v in CurrentVar {
		var:=CurrentVar[k]
		mod(k,2) ? var:=strReplace(var,a_space)
		mod(k,2) ? %var%:=CurrentVar[k+1]
	}
	var:=v:=CurrentVar:=""
}
	
msgbox, %		FirstName "`n"
			.	Surname "`n"
			.	Street

Hol3yMol3y wrote:
30 Jun 2019, 03:55
I also looked into .ini files but these don't seem to have any benefit and I don't need the Header functionality.
for the above ini() function if you don't want a header simply use an empty one []

cheers,
Hol3yMol3y
Posts: 19
Joined: 10 Jun 2019, 04:08

Re: Passing variables between scripts

04 Jul 2019, 03:01

SpeedMaster wrote:
30 Jun 2019, 12:26
Hol3yMol3y wrote:
30 Jun 2019, 03:55
So, basically my question is this: does anyone know an easy way to make AHK read a txt file of variables and declare them all as written? Alternatively, if it can't be done, can someone help me write a Loop function to parse it line by line?
If I understand correctly, you want to import the whole stuff ( variable name + content) :shock:
experimental script only !! :roll:

Code: Select all

#SingleInstance forcce
SetWorkingDir, %a_scrpitdir%


; Frist create a test file (test.txt)
fileContent =
(
FirstName := Bob
Surname := Jones
Street := Jones Street
)
replaceFile("test.txt", fileContent)

replaceFile(File, Content)
{
	FileDelete, %File%
	FileAppend, %Content%, %File%
}


; Parse the test file and declare variables
fileread, vars, test.txt

loop, parse, vars, "`n" 
{
	CurrentVar:=strsplit(a_loopfield, "=", ":")
	for k, v in CurrentVar {
		var:=CurrentVar[k]
		mod(k,2) ? var:=strReplace(var,a_space)
		mod(k,2) ? %var%:=CurrentVar[k+1]
	}
	var:=v:=CurrentVar:=""
}
	
msgbox, %		FirstName "`n"
			.	Surname "`n"
			.	Street

Hol3yMol3y wrote:
30 Jun 2019, 03:55
I also looked into .ini files but these don't seem to have any benefit and I don't need the Header functionality.
for the above ini() function if you don't want a header simply use an empty one []

cheers,
Thanks SpeedMaster! This code works well for my purposes. I would love to try to understand this part of the script more:

mod(k,2) ? var:=strReplace(var,a_space)
mod(k,2) ? %var%:=CurrentVar[k+1]
var:=v:=CurrentVar:=""

I get a headache trying to understand all of the assignments in that last line haha.
User avatar
SpeedMaster
Posts: 300
Joined: 12 Nov 2016, 16:09

Re: Passing variables between scripts

04 Jul 2019, 17:58

Hol3yMol3y wrote:
04 Jul 2019, 03:01
I would love to try to understand this part of the script more:

mod(k,2) ? var:=strReplace(var,a_space)
mod(k,2) ? %var%:=CurrentVar[k+1]
var:=v:=CurrentVar:=""

I get a headache trying to understand all of the assignments in that last line haha.
:? :facepalm:

Code: Select all

CurrentVar:=strsplit(a_loopfield, "=", ":")     ; split current line in 2 parts and correct the syntax
var:=strReplace(CurrentVar[1],a_space)          ; get rid of the spaces for the variable name
mod(k,2)                                        ; obfuscated way to say if (k=1)
CurrentVar[k+1]                                 ; obfuscated way to say currentvar[2]
var:=v:=CurrentVar:=""                          ; fancy way to clear all unnecessary variables
the for-loop is also useless, the values should have been assigned directly %var%:=CurrentVar[2] :D
Helgef
Posts: 3862
Joined: 17 Jul 2016, 01:02
Contact:

Re: Passing variables between scripts

05 Jul 2019, 03:05

@SpeedMaster, please note that x ? y alone is not valid syntax. If you mean to use the conditional operator ?:, you have to include all the symbols and operands, ie., x ? y : z.

Cheers.
User avatar
SpeedMaster
Posts: 300
Joined: 12 Nov 2016, 16:09

Re: Passing variables between scripts

05 Jul 2019, 03:48

Helgef wrote:
05 Jul 2019, 03:05
...you have to include all the symbols and operands, ie., x ? y : z
do you mean something like this ?

Code: Select all

mod(k,2) ? var:=strReplace(var,a_space) :
why ? :think:
Helgef
Posts: 3862
Joined: 17 Jul 2016, 01:02
Contact:

Re: Passing variables between scripts

05 Jul 2019, 04:31

No, I mean something like mod(k,2) ? var:=strReplace(var,a_space) : z, you cannot leave out any symbol or operand.
Why?
Because x ? y has no documented meaning. Just like these are undocumented,

Code: Select all

msgbox % 1 <>< 2		; the fish operator
msgbox % 1 <(.)(.)> 2	; the staring eyes operator
would you use them? ;)

Cheers.
Rohwedder
Posts: 2058
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Passing variables between scripts

05 Jul 2019, 08:26

Hallo,
(.) is not an operator but just the numerical value between -0 and 0
Try:

Code: Select all

MsgBox,% -0<(.) And (.)<0
Helgef
Posts: 3862
Joined: 17 Jul 2016, 01:02
Contact:

Re: Passing variables between scripts

05 Jul 2019, 08:30

No it isn't an operator, that was the point, it is invalid syntax, just like x?y.
User avatar
jeeswg
Posts: 6558
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Passing variables between scripts

05 Jul 2019, 10:29

Two notes:

Code: Select all

;invalid ternary operator (fails in AHK v2, and sometimes in AHK v1):
		mod(k,2) ? var:=strReplace(var,a_space)
		mod(k,2) ? %var%:=CurrentVar[k+1]

;alternatives:
		mod(k,2) && var:=strReplace(var,a_space)
		mod(k,2) && %var%:=CurrentVar[k+1]

		mod(k,2) ? (var:=strReplace(var,a_space)) : 0
		mod(k,2) ? (%var%:=CurrentVar[k+1]) : 0

;succint:
	var:=v:=CurrentVar:=""

;equivalent to:
	CurrentVar := ""
	v := CurrentVar
	var := v
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
SpeedMaster
Posts: 300
Joined: 12 Nov 2016, 16:09

Re: Passing variables between scripts

05 Jul 2019, 19:31

Helgef wrote:
05 Jul 2019, 04:31
Because x ? y has no documented meaning.
?: Ternary operator This operator is a shorthand replacement for the if-else statement.
? [v1.0.90+]: short-circuit If operator. This operator is a shorthand replacement for the if-without-else statement. For example, (a>b) ? c:=5

Now it's documented. :terms: 8-) (by me)
Helgef wrote:
05 Jul 2019, 04:31
... Just like these are undocumented,

Code: Select all

msgbox % 1 <>< 2		; the fish operator
msgbox % 1 <(.)(.)> 2	; the staring eyes operator
would you use them? ;)
I know that if someone pays me enough money to make a "fish operator", I'll probably make one. :think:
even if I liked this one <(.)(.)> more :roll:

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], Flipeador, Google [Bot], ilhom, TheBeginner and 200 guests