I have searched around quite a bit and have failed to find an answer. In AutoHotKey, I am not sure the difference when a single percent is used near the beginning of a line, and when a variable is enclosed between two percent signs. I usually use trial and error to find when I use one or the other, I am hoping someone could shed some light on what the difference is or explain what it is actually doing.
Here are some examples of this in action.
Example 1: I noticed if you have multiple variables along with text, scripts tend to go with the preceding percent. Such as:
some_val := Clipboard
loop 5
msgbox % "Index:" . A_Index . ", variable:" . some_val
Example 2: I often see this as well, and sometimes it appears it must be used. Is this true?
some_variable := "test text to send"
Send, %some_variable%
Wrapping in double percent signs is legacy AHK and basically there is no need to ever use it anymore. Only reason to wrap in double % would be being stuck behind in the old times, or maybe one could argue it also being more convenient, or something, to write in some cases, but I'm not buying it.
The legacy syntax is replaced by expression syntax.
The expression syntax is closer to how many other languages behave. AHK legacy syntax really is a mess.
All legacy commands (MsgBox for example) use the old legacy syntax on each parameter (unless otherwise specified).
If you specify a % followed up by a space at the start of the parameter, you're forcing AHK to evaluate an expression on that parameter instead of reading it as a legacy text parameter.
Example:
MsgBox, 5+5
We're using a legacy command, we're not starting the parameter off with a % and a space, so we're using the legacy syntax. The MsgBox is going to print the literal text 5+5 instead of 10.
MsgBox, % 5+5
Again, legacy command, but now we're forcing AHK to evaluate an expression here, 5+5.
The result of expression's evaluation is going to be passed onto the MsgBox command and the MsgBox is going to print 10.
If we wanted to MsgBox to print the literal text 5+5, and use the expression syntax to do it, we'd do MsgBox, % "5+5".
Quotation marks in expression syntax mean we're specifying a string.
Well then there's the problem of knowing when you're in expression syntax, and when you're in the legacy syntax.
By default, you're basically always in an expression.
You leave it by for example using a command or = to assign.
If the difference between a command and a function isn't clear to you, here's an example:
Command, % 7+3, % MyCoolArray[4], % SomeOtherNiceFunction(), % false
Function(7+3, MyCoolArray[4], SomeOtherNiceFunction(), false)
In the command we specified a % followed up by a space to evaluate the expressions on each parameter, and in the function, we didn't have to do that since we're already in an expression.
And if you're not clear on the difference between = and :=,
= is legacy and deprecated, it assigns plain text to a variable
:= assigns the result of an expression to a variable.
So that's what I could write from on top of my head.
If you had some more complex examples, I could try showing on them. Maybe convert some code you may have over to expression syntax, make it 100% free of legacy syntax.
And here's a good page on the documentation you should give a read:
https://www.autohotkey.com/docs/Language.htm
Related
Been stuck for a while, hoping someone with experience could help me a bit...
Right now I'm reading Ini like this three times but wish to do it dynamically to improve my codes in the long run.
IniRead, Alert_price_low, %TrackerFile%, Item, Alert_price_low
IniRead, Alert_price_high, %TrackerFile%, Item, Alert_price_high
IniRead, Alert_checkbox, %TrackerFile%, Item, Alert_checkbox
I made this function below trying to read it dynamically, but doesn't return anything...
FindIniSettings(TrackerFile, Alert_checkbox)
FindIniSettings(TrackerFile, x){
x := IniRead, %x%, TrackerFile, Item, %x%
return x
}
How my Ini file content looks like:
[Item]
Alert_price_low=777
Alert_price_high=999
Alert_checkbox=1
Thanks!
The problem here is pretty much just with the usage of the new expression syntax.
Seems you've been using only the deprecated legacy syntax, and functions are not apart of that.
So first problem is here
FindIniSettings(TrackerFile, Alert_checkbox)
Here you're not in legacy syntax, so to specify strings you quote them.
FindIniSettings(TrackerFile, "Alert_checkbox")
(And I'm assuming TrackerFile here is a variable that contains some iniFileNameOrPath.ini string)
Also, you're not storing the return value of this function anywhere.
Second problem is here
x := IniRead, %x%, TrackerFile, Item, %x%
Firstly, commands are legacy, they don't return values like that.
You can't use an := operator to get the return value.
They return values only by writing the output to the requested variable, which will be specified in the first parameter of the command.
You specified the output variable to be named whatever x contains. This is no good since you can't possibly know what the output variable is going to be during runtime (without some unnecessary extra tricks).
Also, be quite confusing to name the output to be the same as input key. Though, that would work.
So two problems there, := and the first %x%, and there's still some more to go which is right here:
, TrackerFile,
Commands are legacy, as mentioned above, they exclusively use the legacy syntax in every parameter (unless otherwise specified in the documentation).
So, you're passing in the literal text "TrackerFile", not whatever string should be stored inside the variable named TrackerFile.
In legacy syntax, you refer to the contents of a variable by wrapping it around in %%, as you've been doing before. Maybe you just forgot here.
But really, I'd recommend you try to get used to ditching the legacy syntax. So what you could/should do, is starting off the parameter with a single % followed up by a space. This makes ahk interpret an expression on that parameter, as opposed to using the legacy syntax. In the modern expression syntax you refer to a variable just by typing its name. No stupid %%s needed.
So here's the fixed script you should end up with. I made this example fully legacy syntax free as a demonstration:
TrackerFile := "test.ini"
returnValueOfThisFunction := FindIniSettings(TrackerFile, "Alert_price_low")
MsgBox, % "Yay, the function returned a value for us:`n" returnValueOfThisFunction
return
FindIniSettings(TrackerFile, key)
{
;even specified the string "Item" explicitly as a string
;this is not needed, but it just looks right to me
;I wouldn't want to specify a legacy parameter there
;in the middle of all this
IniRead, output, % TrackerFile, % "Item", % key
MsgBox, % "Now the variable named ""output"" contains the result of the above command (" output ").`nWe can now return it to the caller."
return output
}
So yeah, pretty much just problems understanding legacy syntax vs expression syntax.
You can give a read to a previous answer of mine here about usage of %% vs % .
And here's a good page on the AHK documentation about the scripting language and legacy vs. modern expression.
What is the correct name for the situation where a Matlab-script calls a function, but provides arguments without parentheses?
Example:
clear xx
Alternatively, I could use parentheses and transfer a string with the variable name:
clear('xx')
How can I distinguish between both alternatives when googling for a solution?
Bonus Question: How can I put the content of a variable into a call that is NOT using parentheses? Specifically, a build-script using mcc with a dynamic -o filename option; calling mcc with parentheses would also be acceptable, but I don't know how to google that, hence this question.
Thank you!
When you call a function without the brackets, it is called command syntax. Here are three links to relevant documentation:
syntax
command vs function syntax
scripts and functions
Bonus answer
You cannot use a variable when using command syntax. From the docs:
When calling a function using command syntax, MATLAB passes the arguments as character vectors.
So it would work like so:
abc = zeros(10); % Some matrix called abc
mystring = 'abc' % A string containing the variable name
% Option 1:
clear('abc') % Clears the variable abc
% Option 2:
clear abc % As per above docs quote, interpreted as clear('abc')
% Option 3:
clear mystring % As per option 2, interpreted as clear('mystring') so doesn't work
% Option 4:
clear(mystring) % Interpreted as clear('abc') so works as expected
When calling mcc as you suggest in the question, the tooltip shows you can in fact use function syntax, despite the documentation being entirely shown using command syntax.
Notes
Using brackets is standard practise in MATLAB, since you also cannot get output values from a function when using command syntax.
Also from the 3rd docs link above, you can see a message discouraging the use of command syntax when using MATLAB.
Caution: While the unquoted command syntax is convenient, in some cases it can be used incorrectly without causing MATLAB to generate an error.
In functions, the MATLAB editor displays a warning when a defined variable is not subsequently used before the function ends or before the variable is overwritten. This obviously tells me that the editor has a way of searching for occurrences of given variables in the code.
Can I do this manually? The Find function is obviously limited here, since it only searches the body of text in the editor window (including comments) for matches of the search string. This makes it very inconvenient when searching for variables with short names (such as the by me commonly used "a").
I cannot tell you about previous versions of the built-in editor, but at least from 2011b, the righthand side margin of the editor creates color tags for:
Warnings, tagged in orange
Errors, tagged in red color
Variable/function occurrence: tagged in dark gray, for selected text.
The third of them is what you are looking for. You just have to double click on a variable name or a function name to select it and your Matlab editor will automatically highlight the rest of the occurrences of the very same identifier, tagging them on the righthand side ribbon with the grey mark I mentioned above.
You can limit the search to match case and whole word, which will give you only this variable, either in comment or not.
BTW, you shouldn't use variable names like a,b,c. It makes the code harder to read and to maintain. Even if you have dummy variables like in loops and temporary ones, use for example indexFiles, or tempValue
You can also use some regular expression to match the variable names in your code.
If you'll assume that any variable name is separated from the rest of the code by any of linefeed tab space ! " # $ % & ' ( ) * + , - . / : ; < = > ? [ \ ] ^ `` { | } ~, then you can create a small function that takes the function name as input and outputs the lines in which the variable name is mentioned. However, this approach doesn't separate function names and variable names, but you should have some standard for separating them anyway. I use this approach to change variable names of my MATLAB code (but my code for that is written in awk, not in MATLAB).
And I wonder what you'll do when you have a complex program with thousands or tens of thousands of lines of code and your variables are named a, b, c and so on...
I am trying to translate a .bat file to PowerShell and having trouble with understanding what a few snippets of code is doing:
set MY_VARIABLE = "some\path\here"
"!MY_VARIABLE:\=/!"
What is line 2 above doing? Specially, I dont understand what the :\=/ is doing since I have seen the variable else where in the code being referenced like !MY_VARIABLE!.
The other point of confusion is the below code.
set SOME_VARIABLE=!SOME_ARGUMENTS:\=\\!
set SOME_VARIABLE=!SOME_ARGUMENTS:"=\"!
Also, can you tell me what is going on in lines 3 and 4 above as well?
What would the below variables translate into PowerShell as well?
set TN0=%~n0
set TDP0=%~dp0
set STAR=%*
Any help on this is much appreciated. Thanks.
The !var:find=replace! is string substitution for a variable that is delay-expanded.
http://www.robvanderwoude.com/ntset.php#StrSubst
When you use ! instead of % for a variable, you want DOS to do the variable replacement at execution time (which is probably what you think it does with %, but it doesn't). With %, the variable is substituted at the point that the command is parsed (before it's run) -- so if the variable changes as part of the command, it won't be seen. I think some switch to using ! all of the time, because it gives "normal" behavior.
You can read more about delayed expansion here
http://www.robvanderwoude.com/ntset.php#DelayedExpansion
The first two set variableName= commands use modifiers to expand on the name of the batch file, represented as %0.
%~n0 expands it to a file name, and
%~dp0 expands it to include a drive letter and path.
The final one, %*, represents all arguments passed to the batch file.
Additional information can be found in answers here or here.
Exclamation points (!) i n DOS batch files reference the intermediate value, useful if you are in a for-loop. If you were to use a % instead (in a loop), it would return the same value over and over.
Lines 3 and 4 are setting "SOME_VARIABLE" to the intermediate value of "SOME_ARGUMENTS:\=\" and SOME_ARGUMENTS:"=\", respectively. Again, I'm guessing that these lines are from a loop.
As for the variable assignments, Powershell variable assignments work like this:
$myVariable = "my string"
~dp0 (in DOS batch) translates into the path (with drive letter) of the current bat file. You can get that in Powershell by doing a "get-location".
Why someone would need to set a variable for STAR(*) is beyond me, so I'm assuming there was some encoding issue or other reason that they couldn't just use an asterisk.
~n0 I'm not sure about; maybe someone else knows what that one is.
This is hard to look up: what do the end-of-line commas do in Matlab? In the couple of small tests I've done, they don't seem to make the code behave any different. I'd like to know because they're all over in this code I didn't write (but have to maintain).
Examples of what I mean:
if nargin<1,
% code
end
if isError,
% code
end
try,
% code
while 1,
% even more code
end
catch,
% code
end
According to the documentation for the comma character in MATLAB, one of its functions is to separate statements within a line. If there is only one statement on a line, the comma is not needed. I don't like to see it there, although I know some people write code that way.
As others have pointed out, commas at the end of a line are unnecessary. They are really just for separating statements that are on the same line. mlint and the Editor will even give you a warning if you use one without needing it:
>> mlint comma_test.m
L 1 (C 4): Extra comma is unnecessary.
If you read tightly coded m-files (e.g., many of the built-in MATLAB functions) you will discover a variant of the if ... end construct that is written on one line. Here's an example
if x<0, disp('imaginary'); end
Notice the comma between the x<0 and the disp(...). Apparently the comma tells the MATLAB interpretter that the conditional test has ended. To my knowledge this is only place where a statement (OK, part of a statement) ends with a comma. It's just one of those quirks that true believers come to use without hesitation.
http://web.cecs.pdx.edu/~gerry/MATLAB/programming/basics.html
I think the comma in matlab is like the semicolon in C. It separates commands, so you can put multiple commands in one line separated by commas.
The way your program is written, I believe the commas make no difference.