Page 5 of 7

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 29 Mar 2017, 01:44
by nnnik
Btw the function has to pass the output variable name as a string rather than as a ByRef variable, I don't know if there's a workaround for this.

Code: Select all

;two-way compatible: StringSplit
;MsgBox % A_AhkVersion
vText := "a`tb`tc"

JEE_StringSplit("vOutput", vText, "`t")
MsgBox % vOutput0 " " vOutput1 " " vOutput2 " " vOutput3

oOutput := StrSplit(vText, "`t")
MsgBox % oOutput.MaxIndex() " " oOutput[1] " " oOutput[2] " " oOutput[3]


JEE_StringSplit(vOutput, ByRef vText, vDelims:="", vOmitChars:="")
	%vOutput%0 := 0
	Loop, Parse, % vText, % vDelims, % vOmitChars
		%vOutput%%A_Index% := A_LoopField, %vOutput%0 += 1
A function which works in a similar way to SplitPath:
If someone has written a similar function, please post a link.

Code: Select all

;two-way compatible: split to named vars
q:: ;split text to named variables (rather than numbered variables)
vText := "key=value1|value2|value3"
vCount := JEE_StrSplitToVars(vText, "=|", "", vKey, vValue1, vValue2, vValue3)
MsgBox % vCount " | " vKey " " vValue1 " " vValue2 " " vValue3

vText := "03:02:01 04/05/2006" ;DMY
vCount := JEE_StrSplitToVars(vText, ": /", "", vHour,vMin,vSec,vDay,vMonth,vYear)
MsgBox % vCount " | " vYear " " vMonth " " vDay " " vHour " " vMin " " vSec

JEE_StrSplitToVars(ByRef vText, vDelims:="", vOmitChars:="", ByRef v1:="", ByRef v2:="", ByRef v3:="", ByRef v4:="", ByRef v5:="", ByRef v6:="", ByRef v7:="", ByRef v8:="", ByRef v9:="", ByRef v10:="", ByRef v11:="", ByRef v12:="")
	vCount := 0
	Loop, Parse, % vText, % vDelims, % vOmitChars
		if (A_Index <= 12)
			v%A_Index% := A_LoopField
	return vCount
Please use Arrays instead of pseudo Arrays. They are always better than pseudo Arrays. As things are right now I would advertise against using your Converter.

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 29 Mar 2017, 14:31
by jeeswg

I've explained above the advantages of using 'StringSplit' for a small number of numbered variables (and a custom variant for named variables), over a numbered array. Btw I intend to use both arrays, and pseudo-arrays (of most likely fewer than 10 variables). There are some situations like the frequency counting of strings where arrays are far better than pseudo-arrays.

As ever, any converter of mine has everything *optional*, and keeping StringSplit in AHK v2 by replacing it with a custom function, would be turned *off* by default. It's a mindset, are variables evil? Do we have to use arrays for *everything*?

Sometimes I think this is the problem with programmers and indeed people generally, you get stuck in one paradigm, and then you get stuck in the opposite paradigm. I often move back and forth between ideas and explore numerous possibilities, by experience you find out what works best, what tweaks to make to your own programs, and the external programs you use.

For every paradigm, there is an equal and opposite anti-paradigm.

An example of developing functions. At the moment I am thinking that my StrIn and StrStarts/StrContains/StrEnds functions, should treat the needle text literally by default rather than as a comma-separated list, and that they should only be seen as lists if a character is specified in the delimiter parameter such as pipe or comma. I've also decided that Str(Trim)Left/Right should assume 1 character, if the length parameter is omitted, I'm somewhat surprised that the existing AHK functions don't do this already.

I have a converter script essentially finished, I'm just trying to make it more complete by making it ready for (almost) all outgoing commands, i.e. I'm adding in support for the commands I don't use personally.

My script converter, you might just lllike it.


List of commands/functions being removed (58):

Code: Select all

;old AHK v1 command/functions
[EDIT:] List of commands/functions being removed (58) (replacement options):

Code: Select all

;replaceable: fairly easy
Asc (Ord)
EnvAdd/EnvSub (for dates: DateAdd/DateDiff)
EnvUpdate (SendMessage with WM_SETTINGCHANGE)
FileCopyDir/FileCreateDir/FileMoveDir/FileRemoveDir (DirCopy/DirCreate/DirMove/DirDelete)
FileSelectFile/FileSelectFolder (FileSelect, DirSelect)
IfExist/IfNotExist (FileExist)
IfInString/IfNotInString (InStr)
IfWinActive/IfWinNotActive (WinActive)
IfWinExist/IfWinNotExist (WinExist)
StringLen (StrLen)
StringLower/StringUpper (StrLower/StrUpper)
URLDownloadToFile (Download)
WinGetActiveStats (WinGetTitle, WinGetPos)
WinGetActiveTitle (WinGetTitle)
WinMenuSelectItem (MenuSelect)

;replaceable: fiddly / awkward / very awkward
FileReadLine (FileRead and 'Loop, Parse', or StrSplit, or 'Loop, Read', or File object and ReadLine)
IfMsgBox (get return value from MsgBox function)
SetBatchLines (Sleep multiple times)
SetFormat (Format multiple times)
StringGetPos (InStr)
StringLeft/StringRight/StringTrimLeft/StringTrimRight (SubStr)
StringMid (SubStr)
StringReplace (StrReplace)
StringSplit (StrSplit)

;replaceable: use mathematical operators instead:

;no replacement:
Transform (some functionality removed i.e. HTML subcommand)

;old command is now part of a existing function
DriveSpaceFree (DriveGet, which already existed in AHK v1)

;old command has been split up into new functions
Process (5 subcommands each to a function)
Transform (i.e. Deref, other subcommands available by other means or removed)
WinGet (14 subcommands each to a function)
WinSet (11 subcommands to 10 functions, 'Disable/Enable' to 'Enabled' on/off)
The more awkward conversions, i.e. not one-liners that are easily parsed:
- pseudo-arrays to arrays (StrSplit, WinGetControls/WinGetControlsHWND/WinGetList, RegExMatch?/RegExReplace?)
- 'notification' functions currently have no replacements: Progress/SplashImage/SplashTextOff/SplashTextOn
- 'if var in/contains' currently have no replacements
- SetFormat (use the Format function on individual items, versus a SetFormat mode on all subsequent items)
- Return: the last parameter is returned (rather than the first parameter)
- objects: ComObjUnwrap and ComObjEnwrap
- also being removed: #MaxMem, #NoEnv, AutoTrim, SetBatchLines, FileReadLine, IfMsgBox, Transform (e.g. HTML subcommand, note that Deref will be a separate function)
- note: Process, WinGet and WinSet will no longer exist, and will be replaced with separate functions, however, this is reasonably easy to parse, the exception being the functions involving arrays: WinGetControls/WinGetControlsHWND/WinGetList
- note: the most awkward parameter changes: MsgBox/InputBox, InStr/SubStr, StrReplace (also: TrayTip, Sort, Loop, RegRead/RegWrite)
- note: inconvenient command removals that I plan to replace with custom functions: StringSplit, StringTrimLeft, StringTrimRight, StringLeft, StringRight

Key summary of changes:

Process, WinGet, WinSet will be removed, and replaced with more specific functions:

Code: Select all

Process, Close -> ProcessClose
Process, Exist -> ProcessExist
Process, Priority -> ProcessSetPriority [name change]
Process, Wait -> ProcessWait
Process, WaitClose -> ProcessWaitClose

WinGet, ControlList -> WinGetControls [name change]
WinGet, ControlListHwnd -> WinGetControlsHwnd [name change]
WinGet, Count -> WinGetCount
WinGet, ExStyle -> WinGetExStyle
WinGet, ID -> WinGetID
WinGet, IDLast -> WinGetIDLast
WinGet, List -> WinGetList
WinGet, MinMax -> WinGetMinMax
WinGet, PID -> WinGetPID
WinGet, ProcessName -> WinGetProcessName
WinGet, ProcessPath -> WinGetProcessPath
WinGet, Style -> WinGetStyle
WinGet, TransColor -> WinGetTransColor
WinGet, Transparent -> WinGetTransparent

WinSet, AlwaysOnTop -> WinSetAlwaysOnTop
WinSet, Bottom -> WinMoveBottom [name change]
WinSet, Disable -> WinSetEnabled [name change][WinSetEnabled twice]
WinSet, Enable -> WinSetEnabled [name change][WinSetEnabled twice]
WinSet, ExStyle -> WinSetExStyle
WinSet, Redraw -> WinRedraw [name change]
WinSet, Region -> WinSetRegion
WinSet, Style -> WinSetStyle
WinSet, Top -> WinMoveTop [name change]
WinSet, TransColor -> WinSetTransColor
WinSet, Transparent -> WinSetTransparent

Btw I have been making parameter summaries for each command: e.g. 'SplitPath IBBBBB', (or which is in effect simply 'BBBBBB'), there basically seems to be 2 types of parameter, 'ByRef' and normal, but sometimes parameters can be a bit of both, so if all the possible parameter properties can be clearly defined and given names, that would be helpful. I.e. how many 'types' of parameter are there, 'ByRef', 'normal', is there only one type of 'hybrid' or multiple types of 'hybrid'. If I recall correctly PostMessage/SendMessage had particularly flexible parameters.

Cmd, var -> Func(var) (stays the same)
Cmd, var%var2% -> Func(var1%var2%) (stays the same)

Cmd, text -> Func("text")
Cmd, %var% -> Func(var)
Cmd, % "text" -> Func("text")
Cmd, % var -> Func(var)
Cmd, % var%var2% -> Func(var%var2%)

normal (nonstandard):
Cmd, var -> Func(var)

Variables and Expressions
For backward compatibility, command parameters that are documented as "can be an expression" treat an isolated name in percent signs (e.g. %Var%, but not Array%i%) as though the percent signs are absent. This can be avoided by enclosing the reference in parentheses; e.g. Sleep (%Var%).

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 29 Mar 2017, 14:41
by nnnik
Using individual variables is slower and doesn't free ressources properly. You can use arrays with normal code and object code. You can't do that with variables.

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 30 Mar 2017, 19:17
by jeeswg
@nnnik. Interesting comments re. performance. If you or anyone has any further details as to why arrays would be faster than variables, that would be interesting to read up on.

You might say that variables are like walking, and objects are like running, and therefore you should never walk in your daily life. I, in fact, like arrays, especially for operating on big lists. And indeed some benchmark tests I have done, on reversing a list, suggest their speed.

How to optimize the speed of a script as much as possible. - Page 5 - AutoHotkey Community ... 39#p140139

Also, reflecting my love of objects/arrays, see:

case sensitive/case insensitive arrays (maintain key order, no key autosort) - AutoHotkey Community
Firefox/Chrome, get tab names/focus tab - AutoHotkey Community
log hotkeys, get extended hotkey info, interact with the *right* window (Hotkey command with FunctionObject example) - AutoHotkey Community


For the most part I have found workarounds for issues relating to AHK v2.

However this is one that really dismays me:

RegExMatch options O and P were removed; O (object) mode is now mandatory.
Note: it was StringSplit and not RegExMatch that caused my initial concern about variables v. arrays.

My obvious recommendation would be: V (variable) mode, otherwise, *potentially*, I could write a go-between function for RegExMatch, to achieve the old functionality. You have to understand that if there is no realistic benefit to using objects in such circumstances, (unless I want to, and I can already,) and if it's easier to write a go-between function than go through the hell of converting all the scripts, then reluctantly, I like the RegExMatch function, I will always use JEE_RegExMatch instead of RegExMatch, because presented with the situation, that is the best outcome, and that is what must happen.

I have done all sorts of conversions, and accepted all of the necessary burdens, but I really don't want to go through *ALL* my RegEx uses and convert all of these to objects.

As someone who supports the syntax changes, parameter alterations, command renaming and splitting, and general direction of travel, I hate it whenever I have the mindset, whenever I catch myself thinking: 'I wish we were still using AutoHotkey v1'.

The deep impact of some changes may not be immediately obvious.

These things were there for a reason, I wish people were more vocal about it. I don't mind a *LOT* of conversion, and I mean a *LOT*, for changing the names of things, or restructuring commands/functions, but removing functionality should really be advised against.


I have collected some information which is crucial for conversion. It determines, when converting command parameters to function parameters, whether to treat them as variable names or as literal text. If anyone has done some similar lists I would be interested to know.

I think of the AHK commands as '1', '1X' and '2':
- '1' are the old commands to be kept.
- '1X' are the old commands to be removed.
- '2' are the new commands(/functions), some of which replace old commands.

'C' command name
'X' convert to expression style
'I' input variable name, don't convert
'O' output variable name, don't convert
'B' ByRef variable name, don't convert (e.g. WinGetPos, X Y W H variables)

The 'O' is very important because you get:
CmdOrFuncName, OutputVar, Param2, Param3
which becomes:
OutparVar := CmdOrFuncName(Param2, Param3)
The 'O' should only appear once per command. When there are multiple 'output' parameters, I usually label these as 'B'.

If I could introduce a 'hybrid' category, or different types of 'hybrid' category (if there is more than one type of 'hybrid'), this could help improve the converter. I don't mind not adding it in, however, if someone already had the information, or found it easy to produce a list, I could incorporate it. Otherwise, it just means a few more occasional manual corrections are required, after doing automatic conversion.

From experience, testing it, the list is good enough for almost perfect conversion, but I cannot 100% guarantee the accuracy of the list.

To generate such a list. Basically you download the help htms, from GitHub, or extract them from AutoHotkey.chm (via HTML Help or 7-Zip), and get everything within 'syntax' tags. Then you parse them, checking for references in the parameter names for Output/Input. Then you manually check them. Some commands like 'Click' and around 10 of the AHK v2 commands are not currently in any syntax html blocks.

This link has example syntax lists for AHK v1/v2, links to source htms, and a link with code, for extracting syntax text from htms:
commands as functions (AHK v2 functions for AHK v1) - AutoHotkey Community ... 82#p139582

Code: Select all

;AHK v1 commands kept in AHK v2 (with their AHK v2 parameters)
BlockInput	CX
Click	CX
ClipWait	CXX
ControlClick	CXXXXXXXX
ControlFocus	CXXXXX
ControlGetFocus	COXXXX
ControlGetText	COXXXXX
ControlSend	CXXXXXX
ControlSendRaw	CXXXXXX
ControlSetText	CXXXXXX
CoordMode	CXX
Critical	CX
DetectHiddenText	CX
DetectHiddenWindows	CX
Drive	CXXX
DriveGet	COXX
Edit	C
EnvGet	COX
EnvSet	CXX
Exit	CX
ExitApp	CX
FileAppend	CXXX
FileCopy	CXXX
FileCreateShortcut	CXXXXXXXXX
FileDelete	CX
FileEncoding	CX
FileGetAttrib	COX
FileGetShortcut	CXBBBBBBB
FileGetSize	COXX
FileGetTime	COXX
FileGetVersion	COX
FileInstall	CXXX
FileMove	CXXX
FileRead	COX
FileRecycle	CX
FileRecycleEmpty	CX
FileSetAttrib	CXXX
FileSetTime	CXXXX
FormatTime	COXX
GroupActivate	CXX
GroupClose	CXX
GroupDeactivate	CXX
GuiControl	CXXX
GuiControlGet	COXXX
Hotkey	CXXX
ImageSearch	CBBXXXXX
IniDelete	CXXX
IniWrite	CXXXX
KeyHistory	C
KeyWait	CXX
ListHotkeys	C
ListLines	CX
ListVars	C
MouseClickDrag	CXXXXXXX
MouseGetPos	CBBBBX
MouseMove	CXXXX
OutputDebug	CX
Pause	CXX
PixelGetColor	COXXX
Random	COXX
RegDelete	CXX
RegRead	COXX
RegWrite	CXXXX
Reload	C
Send	CX
SendEvent	CX
SendInput	CX
SendLevel	CX
SendMode	CX
SendPlay	CX
SendRaw	CX
SetCapsLockState	CX
SetControlDelay	CX
SetDefaultMouseSpeed	CX
SetKeyDelay	CXXX
SetMouseDelay	CXX
SetNumLockState	CX
SetRegView	CX
SetScrollLockState	CX
SetStoreCapslockMode	CX
SetTimer	CXXX
SetTitleMatchMode	CX
SetWinDelay	CX
SetWorkingDir	CX
Shutdown	CX
Sleep	CX
SoundBeep	CXX
SoundGet	COXXX
SoundPlay	CXX
SoundSet	CXXXX
StatusBarGetText	COXXXXX
StringCaseSense	CX
Suspend	CX
SysGet	COX
Thread	CXXX
TrayTip	CXXX
WinActivate	CXXXX
WinActivateBottom	CXXXX
WinGetClass	COXXXX
WinGetTitle	COXXXX
WinMaximize	CXXXX
WinMinimize	CXXXX
WinMinimizeAll	C
WinMinimizeAllUndo	C
WinRestore	CXXXX
WinSetTitle	CXXXXX
WinWaitActive	CXXXXX
WinWaitClose	CXXXXX
WinWaitNotActive	CXXXXX

;AHK v1 commands not in AHK v2 with their parameters (note: Asc is a function)
AutoTrim	CX
DriveSpaceFree	COX
EnvDiv	CIX
EnvMult	CIX
EnvUpdate	C
FileCopyDir	CXXX
FileCreateDir	CX
FileMoveDir	CXXX
FileReadLine	COXX
FileRemoveDir	CXX
FileSelectFile	COXXXX
FileSelectFolder	COXXX
IfEqual	CIX
IfExist	CX
IfGreater	CIX
IfGreaterOrEqual	CIX
IfInString	CIX
IfLess	CIX
IfLessOrEqual	CIX
IfMsgBox	CX
IfNotEqual	CIX
IfNotExist	CX
IfNotInString	CIX
IfWinActive	CXXXX
IfWinExist	CXXXX
IfWinNotActive	CXXXX
IfWinNotExist	CXXXX
Process	CXXX
Progress	CXXXXX
SetBatchLines	CX
SetEnv	CIX
SetFormat	CXX
SoundGetWaveVolume	COX
SoundSetWaveVolume	CXX
SplashImage	CXXXXXX
SplashTextOff	C
SplashTextOn	CXXXX
StringGetPos	COIXXX
StringLeft	COIX
StringLen	COI
StringLower	COIX
StringMid	COIXXX
StringReplace	COIXXX
StringRight	COIX
StringSplit	COIXX
StringTrimLeft	COIX
StringTrimRight	COIX
StringUpper	COIX
Transform	COXXX
UrlDownloadToFile	CXX
WinGetActiveStats	CBBBBB
WinGetActiveTitle	CO

;new AHK v2 commands(/functions) with their parameters
DateDiff	COIXX
Deref	COX
DirCopy	CXXX
DirCreate	CX
DirDelete	CXX
DirExist	COX
DirMove	CXXX
DirSelect	COXXX
Download	CXX
FileSelect	COXXXX
MonitorGet	CXXXXX
MonitorGetCount	CO
MonitorGetName	COX
MonitorGetPrimary	CO
MonitorGetWorkArea	CXXXXX
ProcessClose	CX
ProcessExist	CX
ProcessSetPriority	CXX
ProcessWait	CXX
ProcessWaitClose	CXX
RegDeleteKey	CX
StrLower	COIX
StrUpper	COIX
Type	COX
WinGetControls	COXX
WinGetControlsHwnd	COXX
WinGetCount	COXX
WinGetExStyle	COXX
WinGetList	COXX
WinGetMinMax	COXX
WinGetProcessName	COXX
WinGetProcessPath	COXX
WinGetStyle	COXX
WinGetTransColor	COXX
WinGetTransparent	COXX
WinMoveBottom	CXXXX
WinMoveTop	CXXXX
WinRedraw	CXXXX
WinSetAlwaysOnTop	CXXXXX
WinSetEnabled	CXXXXX
WinSetExStyle	CXXXXX
WinSetRegion	CXXXXX
WinSetStyle	CXXXXX
WinSetTransColor	CXXXXXX
WinSetTransparent	CXXXXX
Btw I could do with a reliable list of commands/directives/functions/variables.

This is what I've got so far, people might think that it looks definitive, but ultimately it's just a custom user's list, that could have omissions.
list of every command/function/variable from across all versions - AutoHotkey Community ... 42#p131642

It was not easy to find the full list of 'ComObj' and 'Obj' functions for example, which if it had been available would have been a great way to start learning about AHK's treatment of objects. I found out about #DerefChar and #Delimiter by accident. I actually had a conversion script issue, where conversion wouldn't take place because one source listed 'URLDownloadToFile', and then I realised it should have been 'UrlDownloadToFile'.

Thanks for reading.

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 31 Mar 2017, 03:57
by just me
jeeswg wrote:... I will always use JEE_RegExMatch instead of RegExMatch, because presented with the situation, that is the best outcome, and that is what must happen.
You are free to use whatever you want. But why should others want to use it?

You are hell-bent on defining a 'two-way compatible' conversion logic. So try your best respecting the existing syntax rules. If you don't get it, let it be. Why should anything in v2 be changed just to simplify this task?

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 31 Mar 2017, 05:21
by lexikos
jeeswg wrote:You might say that variables are like walking, and objects are like running,
No, I wouldn't. I believe that mindset comes from the fact that objects can be used to do many things that are impractical to do with variables, and some of those things are complicated. When it comes to returning a list/array/sequence/collection of items, there are fewer reasons to recommend pseudo-arrays than arrays, especially to beginners. I think there is not a single case where I would recommend pseudo-arrays to a beginner. Arrays aren't any more complicated than pseudo-arrays if the comparison is restricted to common grounds, and are simpler in some cases.
These things were there for a reason,
Pseudo-arrays were there because arrays did not exist.
... removing functionality should really be advised against.
Functionality, especially redundant functionality, does not inherently have value just because it existed.
It was not easy to find the full list of 'ComObj' and 'Obj' functions for example,
It's not easy to find something when you're looking in the wrong place.

There is a full list of ComObj and Obj functions in the help file index. ComObjParameter, ComObject, ComObjActive, ComObjMissing, etc. are not functions; they are aliases for one function, which is listed as "ComObj...()" (when I wrote it, I thought the "..." would be very obvious). This is explained in the documentation.
... would have been a great way to start learning about AHK's treatment of objects.
I don't think so. I would not recommend the Obj functions as a starting point. I would not recommend the ComObj functions as a starting point for learning about AutoHotkey's objects, unless there is a practical reason (for example, if the user wants to automate a program with a COM API, that provides a good motive to learn).
If anyone has done some similar lists I would be interested to know.
Scintillua-ahk/ahk.lua uses such a list to provide accurate syntax highlighting for v1 and v2 (a077?) scripts. It is based on data that I scraped from the parts of the AutoHotkey source code which define the syntax. (The data was collected by a script I wrote, but I don't know where I put the script.)

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 17 Apr 2017, 21:25
by jeeswg
A post by just me, prompted me to ask whether future code examples in the AHK documentation would use function-style or command-style notation.

Object.HasValue/Contains/KeyOf/FindValue - Page 2 - AutoHotkey Community ... 77#p143377

My preference would be that function-style notation would always be used.

I have also responded to a few of the comments above.

Btw I might release my converter within the next few weeks.


@just me
The RegExMatch/RegExReplace problem is not a two-way compatibility problem. You can use the object 'O' mode in both AHK v1 and v2, and a variable can be used that is equal to 'O)' or 'O' for AHK v1, or blank for AHK v2.

The burden of conversion aside, using objects creates a few problems.

Code: Select all

MsgBox, % vDate1 " " vDate2 " " vDate3 " " vDate4 " " vDate5 " " vDate6
MsgBox, % oDate.1 " " oDate.2 " " oDate.3 " " oDate.4 " " oDate.5 " " oDate.6
MsgBox, % v1 " " v2 " " v3 " " v4
MsgBox, % o.1 " " o.2 " " o.3 " " o.4
It's quite (very) awkward when you use a mix of variables and object key references in the same line. Therefore you are tempted to add additional lines simply to create variables in place of the object references. This reason alone is enough for me to believe that the variable 'V' mode for RegEx is worth maintaining, and was something I discovered since originally flagging up this functionality-removal issue, whilst writing new scripts using the RegEx 'O' mode.

Regarding script maintenance, it's very awkward to make sure you always include the '.' in 'object key as variable' ('PSEUDO-VARIABLE') names. Or double check: was it 'v' or 'o.', or that the '.' was in the right place. It's one of those unfortunate mental burdens I like to avoid while doing rapid, accurate and complicated programming.

Plus it looks uglier and takes up more horizontal screen real estate, significant on longer lines.

Are there not any other programming languages that create variable names based on a pattern e.g. var1/var2/var3, varX/varY/varW/varH, varY/varM/varD?


Re. the index / command lists.

An index of commands is like the dictionary, you expect all the words to be there, you don't contemplate on the intelligent and reasonable justifications for omitting command names. If the index is not 100% complete, you would want to know if and where the alternative complete index is available.

Many thanks, I believe that you have done significant work to the command index, since I last wrote.

It's essentially perfect now, possibly I would add 6 items:
and replace 'Trim' with 'Trim / LTrim / RTrim'.

(#AllowSameLineComments, #DerefChar and #Delimiter are missing but will be removed in AHK v2.)

The 'Scintillua' link you provided is excellent, many thanks. (I discovered that my list was missing Exception and TV_SetImageList.) I would advocate that such a list be available on the AHK help somewhere, possibly referenced at the top or bottom of the command index page.


Re. objects.

One problem I had re. objects, was certainty, and in this regard collecting a list of the AHK functions and AHK help urls was a great start.

jeeswg's objects tutorial (not yet complete) - AutoHotkey Community

I see a lot of quite-good users having trouble with ObjAddRef/ObjRelease/ComObjEnwrap/ComObjUnwrap, I am going to start a new post on Ask For Help for this, after a bit more research. The MSDN links in the help didn't add much. Btw appreciating the concept of reference counting, is not the problem, individual queries come up as you program.

Unfortunately for some AHK issues I think that maybe only half-a-dozen AHK users, if that, *really* know the answers, otherwise it's the blind leading the blind or half-truths, or answers that are based on experience and experimentation but not sound knowledge, especially for questions that are less Winapi-related and more AHK-specific.

We need to 'train' our users, and promote AHK, (including examples based on function-style notation,) to improve our pool of talent. We need to confront any major issues that are confusing the beginners, or as in this case, the experts also. I've been writing tutorials, collecting command/struct/DllCall information, and have been trying to present AHK v2 conversion issues to a wider audience ... there is more to come, including tutorials for: beginners, strings, maths, notes on commands, useful dll functions.

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 18 Apr 2017, 05:33
by nnnik
jeeswg wrote:It's quite (very) awkward when you use a mix of variables and object key references in the same line. Therefore you are tempted to add additional lines simply to create variables in place of the object references. This reason alone is enough for me to believe that the variable 'V' mode for RegEx is worth maintaining, and was something I discovered since originally flagging up this functionality-removal issue, whilst writing new scripts using the RegEx 'O' mode.
There is no logical reason to do this. So I guess this is personal preference.
jeeswg wrote:Regarding script maintenance, it's very awkward to make sure you always include the '.' in 'object key as variable' ('PSEUDO-VARIABLE') names. Or double check: was it 'v' or 'o.', or that the '.' was in the right place. It's one of those unfortunate mental burdens I like to avoid while doing rapid, accurate and complicated programming.
This is because you lack training yourself.

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 10 Sep 2017, 14:39
by jeeswg

Since changes were made to FileRead, I needed to come up with a two-way compatible solution.

Code: Select all

;AHK v1
FileRead, vData, % "*c " vPath

;AHK v1/v2 two-way compatible
oFile := FileOpen(vPath, "r")
oFile.Pos := 0
oFile.RawRead(vData, oFile.Length)

;works on AHK v1.1* and AHK v2 (* with AHK v2 functions for AHK v1)
vPath1 := A_ScriptFullPath
vPath2 := A_AhkPath
vPath2 := vPath1
vSize1 := FileGetSize(vPath1)
vSize2 := FileGetSize(vPath2)
JEE_FileReadBin(vData1, vPath1)
JEE_FileReadBin(vData2, vPath2)
vRet := DllCall("ntdll\RtlCompareMemory", Ptr,&vData1, Ptr,&vData2, UPtr,vSize1<vSize2?vSize1:vSize2, UPtr)
MsgBox(vSize1 " " vSize2 " " vRet)

JEE_FileReadBin(ByRef vData, vPath)
	oFile := FileOpen(vPath, "r")
	oFile.Pos := 0
	oFile.RawRead(vData, oFile.Length)


Dealing with variables instead of object keys can have its advantages.
- E.g. to deal with variables, rather than a mix of variables and object keys, which can be a little awkward to type when some have dots, and some have not.
- E.g. brevity, extreme case: variables: 'a' 'b' 'c' v. object keys: 'o.a' 'o.b' 'o.c'.
- If you are frequently/almost always going to convert the object keys to variables after using RegExMatch, this is an argument for maintaining the RegExMatch variable mode. Otherwise you convert the keys to variables afterwards, not so bad, although somewhat inconvenient.
- Neither StringSplit nor StrSplit output to named variables/keys, something that could be potentially useful.
- If you write a custom function, you can't specify to create variables local to where the function was called from, hence I couldn't make a version of RegExMatch to maintain the variable mode, and I couldn't create a function that works exactly like or similarly to StringSplit to create a pseudo-array (e.g. v1/v2/v3, vY/vM/vD), which can be useful for a small number of variables.

I'm posting this code, partly because if variable mode is removed from RegExMatch, then you need a bit of code to convert the object to variables.

Code: Select all

q:: ;split text to named variables/object keys
;split text to named variables
vText := "aaa,bbb,ccc", vList := "A,B,C"
oTemp := StrSplit(vText, ",")
Loop, Parse, vList, % ","
	v%A_LoopField% := oTemp[A_Index]
oTemp := ""
MsgBox, % vA " " vB " " vC

;split text to named objects keys
vText := "aaa,bbb,ccc", vList := "A,B,C"
oTemp := StrSplit(vText, ",")
o := {}
Loop, Parse, vList, % ","
	o[A_LoopField] := oTemp[A_Index]
oTemp := ""
MsgBox, % o.A " " o.B " " o.C

Code: Select all

w:: ;RegExMatch results from array to variables
vDate := 20060504030201
RegExMatch(vDate, "O)^(?P<Y>\d{4})(?P<M>\d{2})(?P<D>\d{2})", o)
MsgBox, % o.Y " " o.M " " o.D
vList := "Y,M,D"
Loop, Parse, vList, % ","
	v%A_LoopField% := o[A_LoopField]
MsgBox, % vY " " vM " " vD


- It will be easier to both convert and maintain my scripts, by using my JEE_FileReadBin function above, than via other routes. [EDIT: I mention this as an example of how exploring two-way compatibility can make one-way and two-way conversion easier. As it happens, I very much welcome the new support for binary variables in AHK v2, see the updated FileRead function and the new ClipboardAll function.]
- AHK v2 doesn't have a satisfactory way of dealing with the double quotes in command line parameters yet. I came up with a CdLn workaround function, and some other suggestions, here:
AHK v2 and strings - AutoHotkey Community ... 37&t=36833
- Anyhow, whatever is done regarding double quotes or Deref, I now have a fairly good workaround, my CdLn function, for the biggest string problem I've faced related to conversion. Note: this is not about compromising code appearance for the sake of compatibility, it is difficult to find a nice solution for this in AHK v2 full stop.
- I don't see any obstacles at present to two-way compatibility (although it's always possible), apart from Loop. This, if added to AHK v1/v2 would solve the problem, otherwise you go two-way compatible as far as you can:
AutoHotkey v2 alpha (UPDATES) - Page 2 - AutoHotkey Community
Experimental: Loop, LoopFiles, LoopRead, LoopReg and LoopParse now support a function-like syntax, where the entire parameter list is enclosed in parentheses and all parameters are expressions. OTB is also supported.
It would be easy to jump on that and argue for it to solve the two-way compatibility question, but I'm finding the 3 choices quite tough:
- Loop XXX or LoopXXX [EDIT: LoopXXX looks better for LoopFiles/LoogReg/LoopRead, and OK for LoopParse]
- 'Cmd, Arg' or 'Cmd Arg', and Func(Arg) [EDIT: using commas looks better/cleaner, and is more consistent, because you have a separator character between function name and first parameter]
- allow function syntax version [EDIT: my one reservation was that it might look like a function definition, but having woken up the next day, it looks pretty good]

Code: Select all

LoopParse(vText, "`n", "`r")
LoopParse vText, "`n", "`r"
LoopParse, vText, "`n", "`r"

Loop (Parse, vText, "`n", "`r")
Loop Parse(vText, "`n", "`r")
Loop Parse vText, "`n", "`r"
Loop Parse, vText, "`n", "`r"

;what I would do in AHK v1
Loop, Parse, vText, `n, `r
	MsgBox, % A_LoopField

;3 of the AHK v2 options
LoopParse(vText, "`n", "`r") ;[best]
LoopParse vText, "`n", "`r"
LoopParse, vText, "`n", "`r" ;not permissible in AHK v2 at present [best]


The Click command as it is, is very confusing (cf. MsgBox's 'smart' parameters), so I would recommend:

Code: Select all

MouseClick, X, Y, Options
MouseDrag, X1, Y1, X2, Y2, Options
;or possibly:
MouseClick, Options, X, Y
MouseDrag, Options, X1, Y1, X2, Y2
Where Options is a space-separated list.

Possible names:
- Click/MouseClick (I would merge the two commands, and keep one name).
- MouseClickDrag (or possibly MouseDrag) (not great: ClickDrag, Drag).
- MouseMove.
- I would keep the name 'Click' for use with Send/SendInput.

'MouseDrag' is logical, although 'MouseClickDrag' has a certain elegance, and since (a) hotstrings, (b) lack of frequent use, I don't mind the longer 'MouseClick'/'MouseClickDrag' names. Choices. [EDIT: I did also consider 'Drag' by itself, but I don't feel inclined towards it. 'MouseDrag' is not bad/not good. I'm not sure whether 'ClickDrag' is an oxymoron or not.]

[EDIT:] Potentially a mini one-parameter format for Send {Click} could be: e.g. to drag the mouse: Send {Click x10 y10 xd10 yd20}, d for destination (or drag), e.g. to double-click the right mouse button: Send {Click x10 y10 r dc}, 'dc' or perhaps better 'c2' for double-click, perhaps 's10' for speed or 'd10' for a 10-millisecond delay, 'rel' for relative or 'cmr' for CoordMode Relative, 'u'/'d' for up/down (hold/release).

[EDIT:] dx10 dy10 for drag destination coordinates would be easier to parse, and are possibly easier to remember, and look better. E.g. {Click x10 y10 dx10 dy20} {Click x10 y10 r c2 rel}.

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 24 Sep 2017, 23:49
by jeeswg

- It had been a minor wish list item of mine, to introduce something like 'A_DefaultTitle' or 'A_GuiTitle', but it was sufficiently minor that I never mentioned it on any of my wish lists.
- It appears that A_ScriptName in AHK v2 is now intended to fulfil this role, it is designated as read/write at present.
- But I see the potential for mishaps here, as scripts expect A_ScriptName to be a robust, certain variable with fixed contents (cf. A_ScriptFullPath, A_AhkPath).
- Note: I believe that A_InitialWorkingDir was introduced for greater consistency, while at the same time the current change to A_ScriptName would reduce consistency.

Variables and Expressions
The default title for MsgBox, InputBox, FileSelect, DirSelect and GuiCreate.

- MsgBox and InputBox are used very widely, so the parameter order is very important here.
- When I created my own InputBox function I had Text and Default as the first 2 parameters, I use the Text and Default parameters all the time, whereas I almost never use the Title/Options parameters.
- Also, an Options parameter is generally expected as the last parameter.
- So, if this applies to users generally and not just to me, then the following should be contemplated:

Code: Select all

InputBox(Text, Title, Options, Default)
;may be preferable to most users:
InputBox(Text, Default, Title, Options)

MsgBox(Text, Title, Options)

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 25 Sep 2017, 11:58
by jeeswg
For double quotes: "" works in AHK v1, `" works in AHK v2 (or " within single quotes).

\x22 for double quotes, saves a lot of bother in RegEx.

Similarly Chr(34) for general use.

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 02 Oct 2017, 09:58
by jeeswg
It appears that ControlGetPos and ControlMove use Window mode in AHK v1, and Client mode in AHK v2. It also appears that this choice cannot be set.

A possible solution would be:
CoordMode, Control, Window|Client
and an A_CoordModeControl variable.

Alphabetical Command and Function Index
Alphabetical Function Index

[EDIT:] And ControlClick.

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 06 Oct 2017, 22:12
by jeeswg
I mentioned here:
Wish List 2.0 - AutoHotkey Community ... 13&t=36789
>>> SetAhkV2Mode (or an alternative name)
- one mode, or granular settings, on/off, to make certain things function more like they do in AHK v2
I think it would be good to anticipate, in general, this as a solution, when changes are made in AHK v2 to control flow statements/directives/functions/variables. Note: I did not include commands in that list.

So far:
- InStr/SubStr/RegExMatch/RegExReplace (negative offset, RegExMatch object mode)
- A_OSVersion (number rather than string)
- Loop (a mode that when on interprets parameters as expression style in AHK v1)

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 03 Nov 2017, 17:12
by jeeswg
In anticipation of needing to write a Click/MouseClick 'AHK v2 function for AHK v1' at some point in the future, I've produced a JEE_MouseClick function, that may or may not be like the eventual AHK v2 function, however, the logic will be similar.

Code: Select all

;2 (click n times)
;c2 (click n times)
;IgnoreCP (the control panel setting is ignored)
;s0 (speed)
;Swap (if specify left click do right click, and vice versa)

;note: unlike MouseClick, the left and right buttons behave consistently across all systems, even if the user has swapped the buttons via the system's control panel

JEE_MouseClick(vPosX:="", vPosY:="", vOpt:="")
	Loop, Parse, vOpt, % " "
		if (A_LoopField ~= "^(M|R|X1|X2|WU|WD|WL|WR|Middle|Right|WheelUp|WheelDown|WheelLeft|WheelRight)$")
			vWhichButton := A_LoopField
		else if (SubStr(A_LoopField, 1, 1) = "s") && !(A_LoopField = "Swap")
			vSpeed := SubStr(A_LoopField, 2)
		else if (A_LoopField = "Rel") || (A_LoopField = "Relative")
			vRel := "R"
		else if (SubStr(A_LoopField, 1, 1) = "c")
			vClickCount := SubStr(A_LoopField, 2)
		else if (A_LoopField ~= "^\d+$")
			vClickCount := A_LoopField
		else if (A_LoopField ~= "^(D|U|Down|Up)$")
			vEvent := A_LoopField
		else if (A_LoopField = "Swap")
			vDoSwap := 1
		else if (A_LoopField = "IgnoreCP")
			vDoIgnoreCP := 1
	if (vClickCount = 0)
		MouseMove, % vPosX, % vPosY, % vSpeed, % vRel
	SysGet, vAreSwapped, 23 ;SM_SWAPBUTTON := 23
	if !vDoIgnoreCP && vAreSwapped
		vDoSwap := !vDoSwap
	if vDoSwap
		if (vWhichButton = "")
			vWhichButton := "R"
		else if (SubStr(vWhichButton, 1, 1) = "R")
			vWhichButton := "L"
	MouseClick, % vWhichButton, % vPosX, % vPosY, % vClickCount, % vSpeed, % vEvent, % vRel
My expectation would be something like this, to allow mathematics to be performed on the coordinates, and then a space-separated list of options.

Code: Select all

MouseClick, 11, 22, "r rel"
MouseDrag, 11, 22, 33, 44, vOpt
Send, "{Click x11 y22 r rel}"
Send, "{Click x11 y22 dx33 dy44 " vOpt "}"
Options with approximate likelihood of usage:
Options: WhichButton Rel Speed ClickCount Event IgnoreCP Swap

'Swap' and 'IgnoreCP':
- MouseClick: press the left button, a left click is sent.
- Click: press the left button, depending on the control panel setting, a left or a right click is sent.
- My function: use control panel setting (same as Click).
- My function plus 'Swap': opposite of control panel setting (opposite of Click).
- My function plus 'IgnoreCP': ignore control panel setting, 'left means left', 'right means right' (same as MouseClick).
- My function plus 'IgnoreCP' and 'Swap': ignore control panel setting, 'left means right', 'right means left' (opposite of MouseClick).
- Perhaps an 'A_' variable could be introduced, something like 'A_MouseButtonSwap' or 'A_MouseSwapButtons', with a value initially based on the Control Panel value, but that can bypass it, giving the user the ability to choose whether buttons are swapped or not.

I might have used the Click command as the basis instead of the MouseClick command, however, I find the statement on the MouseClick documentation page, that Click is 'easier to use' to be untrue. For example, how can I safely handle if one or more of X/Y/click count may or may not be blank. How exactly does it handle commas. Do I need to use MouseGetPos to explicitly state one or two of the values, if X or Y is blank.

Click doesn't support the R (relative coords) parameter, which could be ambiguous with "R" for "Right".
I'm a bit confused by this, by looking at the documentation for Click, I believe we can just specify 'Rel' or 'Relative'.
Maybe the other Mouse commands should be changed to support flexible parameter ordering similar to Click.
I'm not sure if this means something like:

Code: Select all

Command, "a b c"
Command, "c b a"
;is the same as:
Command, "a", "b", "c"
Command, "c", "b", "a"
- Perhaps this was suggested so that you could perform mathematics on the numeric parameters, however, if the parameters can be in any order, including X/Y/click count, and if those 3 parameters are all numeric with no string prefix, you get the terrible situation of ambiguity that you get now with the current Click command.
- Personally I would be happy to keep the options as one parameter, but to split off X and Y. I don't see it as particularly useful to be able to split up the options.

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 04 Nov 2017, 07:45
by Helgef
Hello :wave:
MouseClick(vPosX:="", vPosY:="", vOpt:="")
It is probably a good idea, instead of smart parameters. Some of the options could have thier own parameter perhaps, like whichButton. Calling the mouse functions MouseXXX benefits searching too. I don't think we should have both click and mouseclick :think:
I'm a bit confused by this
Probably just means exactly that you cannot use R by itself.
n anticipation of needing to write a Click/MouseClick 'AHK v2 function for AHK v1' at some point in the future
So the function should be used when someone wants to run a script written for v2, with the v1 executable? Or am I missing the point? :crazy:


Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 04 Nov 2017, 10:28
by jeeswg
- I've been working on these as you might know:
commands as functions (AHK v2 functions for AHK v1) - AutoHotkey Community ... 37&t=29689
- Eventually the nature of AHK v2's MouseClick/Click and MouseClickDrag(/MouseDrag?) functions will emerge, and I'll want to write functions for them also.
- This is me unusually writing demo versions of functions before I actually know what they'll look like.
- I had had some thoughts about how to overcome some of the current problems with the existing commands, but had felt that to be genuinely useful, I ought to try and create a working prototype function, in order to fully discover and truly resolve all of the problems.
- Funnily enough, I thought that everyone would understand what I meant, that this was part of my project to recreate AHK v2 functions for use in AHK v1, but if even you were a little unsure, then it just goes to show that you should always make yourself doubly clear on the Internet, to the point of being mind-numbing.
- I try to not to be too repetitive because if I say something twice on the forums, just me seems to think I've said it a million times.

- I listed Options above: WhichButton Rel Speed ClickCount Event IgnoreCP Swap.
- Looking back at whenever I've used the MouseClick/Drag functions, these values never vary, they always remain fixed. How many MouseClick lines are sometimes left-click, sometimes right-click? It doesn't seem very likely. Varyingly at a relative/absolute position? Fast/slow mouse move? One/two clicks? It doesn't happen. Clearly if it did, you can use variables within the parameter, like you can for any parameter.
- Since AFAICS, you rarely if ever need the parameter to vary, it made a lot of sense to lump all of the options into one parameter, and not give any of them a separate parameter.
- I'd like to know of any good examples where the Options parameter varies. Cheers.

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 05 Nov 2017, 04:43
by Helgef
- I've been working on these as you might know:
I've seen it, I didn't make the connection for some reason, I'm sure it is clear to most people. To me it seems like the idea of writing functions for v1, that mimics those of v2, is flawed in the sense that it cannot be done in a meaningful way until v2 is done, and then there is no need for it. When it comes to conversion, you will have much bigger problems than converting v1 commands to v2 functions. I sincerely applaud your efforts though :clap: :salute:
MouseDrag is be sufficient imo :thumbup:
- I try to not to be too repetitive because if I say something twice on the forums, just me seems to think I've said it a million times.
While I'm not certain that is true, please don't limit your self for the benifit of others' negativism.

Regarding options and parameters. I do not really use these functions, so I don't know what is suitable.


Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 05 Nov 2017, 06:01
by jeeswg
- The only problems I've had with two-way compatibility are double quotes (there are workarounds) and Loop (no workarounds currently). There may be other problems that I'm as yet unaware of.
- As AHK v2 changes, it's easy to update/rename the 'AHK v2 functions for AHK v1' function definitions. The only inconvenience is if you've converted your AHK v1 scripts to 'pseudo-AHK v2 in AHK v1', or to AHK v2, and then the official AHK v2 functions change and you have to make multiple replacements. It's definitely easier for me to update my massive scripts gradually, than to try and jump to AHK v2 in one go.
- One or two functions required a bit more effort, but it's an interesting challenge, and usually not too difficult. It would be amazing if Coco and lexikos could return and give some feedback on it as AHK v2 becomes more finalised. One area needing review is error handling.
- I wanted function versions of AHK v1 commands anyway, so the nature of the project simply switched focus slightly. Plus polyethene had done the most laborious parts already, and Coco had done some key work on some of the harder functions.
- lexikos has suggested MouseDrag, I really don't mind, MouseClickDrag or MouseDrag.
- Haha it's not so much negativity, it's hard to get the balance right re. clarification/being repetitive. Tbh with just me that only happened once re. some StrXXX function proposal definitions.
- Funnily enough it's not a function that is used too frequently, so you might say it doesn't matter too much how the function ends up. I do find Click a little tricky to use though, still.

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 05 Nov 2017, 06:30
by jeeswg


- I've written various functions for getting/setting control text, which I plan to share hopefully in the next week.
- I had thought that perhaps returning an array would be more logical than returning a string, however, by having all of the functions that get text creating variables and not objects as the default, it's easier in the mind to contemplate the situation: you always expect a variable unless you state otherwise. Note: I have 75 GUI get/set text functions, so it definitely helps to know that returning a variable is the default for all of them. Also, and crucially, if you only want one item's text, do you really want a one-item array, and not a direct string?
- So, I would suggest an options parameter, where you can specify to retrieve an array, as one of the options, which is how I'm writing my functions. This also avoids bother when converting to AHK v2, and options parameters can always be added to in future.
- Most of the time when I want the text of items, I want to retrieve the text of one item e.g. the focused item, a string is preferable here, or I want a list of all the items to look at or store in a text file, again a string is preferable.
- Getting item text as an array, would suggest the need for a StrJoin function e.g. StrJoin(Options, Var1, Var2), StrJoin(Options, Obj*).


- This is relatively minor, but it would be nice to be able to use standard arrays for these e.g. oWinGroup.1.WinTitle. Although you could just delete and recreate a group each time as we do now. I remember when I first started using AHK, feeling surprise that we couldn't edit window groups in a granular way.
- This is a really nice summary, cheers lexikos. I guess it's kind of obvious how it worked, but it's still nice to see it in writing. I like the term 'window specs', although I'd been using the term 'window criteria' up till now, which I also like.

Each window group consists of a list of window specs. A window spec in v1 consists of WinTitle, WinText, ExcludeTitle and ExcludeText. Window specs are evaluated in the order they were added to the group.
I feel that pretty much all of the main conversion issues, have already been either addressed or anticipated by lexikos, and I don't feel particularly that there is anything that I want to address but haven't, so things kind of feel pretty settled at the moment. Perhaps there are some problems to come with control flow statements or directives, I wonder.

Re: conversion logic, v1 = -> v1 := -> v2, two-way compatibility

Posted: 10 Nov 2017, 17:46
by jeeswg

- I have two examples showing a way to do Loop and 'Loop, Parse' via the 'for' loop. This would provide a two-way compatible approach to loops.
- This would be potentially useful if someone had a script that would be fully two-way compatible with the sole exception of loops. Loops have been the major/only remaining obstacle to two-way compatibility at present.
- I had been curious if perhaps a directive (or command) could be used to make Loop in AHK v1, behave like Loop in AHK v2, i.e. treat parameters like function-style parameters. I don't know if the implementation difficulty for that would be easy, medium, or hard.
- Btw I do not plan to replace all instances of Loop and 'Loop, Parse' in my scripts, this is a proof of concept. ... 13&t=36789
- This doesn't handle file or registry loops, although I have written custom functions to do this. Although I didn't write those functions for that purpose.
- Doing everything you can to make a script two-way compatible is an interesting challenge.

Code: Select all

q:: ;loop (via for, two-way compatible)
vOutput := ""
Loop, 5
	vOutput .= A_Index " "
MsgBox, % vOutput

vOutput := ""
for i in,5)
	vOutput .= i " "
MsgBox, % vOutput

w:: ;parsing loop (via for, two-way compatible)
vText := "a,b,c,d,e"
vOutput := ""
Loop, Parse, vText, % ","
	vOutput .= A_LoopField A_Index " "
MsgBox, % vOutput

vText := "a,b,c,d,e"
vOutput := ""
for vKey, vValue in StrSplit(vText, ",")
	vOutput .= vValue vKey " "
MsgBox, % vOutput