TheDcoder Posted July 7, 2018 Share Posted July 7, 2018 (edited) Hello everyone, I am back with yet another strange behaviour in AutoIt While working on my project I stumbled upon this weird error in this script: Local $aArray = ["Foo", "Bar", "Baz"] ; Works ConsoleWrite($aArray[($aArray[0] = "Foo" ? 1 : 2)] & @CRLF) ; Doesn't work ConsoleWrite($aArray[$aArray[0] = "Foo" ? 1 : 2] & @CRLF) Quote Bar "E:\Projects\AutoIt\AIO Test Script.au3" (7) : ==> Unbalanced brackets in expression.: ConsoleWrite($aArray[$aArray[0] = "Foo" ? 1 : 2] & @CRLF) ConsoleWrite($aArray[^ ERROR I am using the ternary operator to dynamically select a different element based on the value inside another element, instead of going the more traditional and simple (as in concept) approach of using If...Else The problem is that the interperter thinks the square brackets are unbalanced . It works if I wrap the entire expression inside curvy brackets (parentheses) I would like to see what the developers have to say about this . IMO this is definitley a bug in the interpreter's parser, I would be happy to open a ticket if we determine that this needs to be fixed. Edited July 8, 2018 by TheDcoder Change title again EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted July 7, 2018 Moderators Share Posted July 7, 2018 TheDcoder, The Help file does suggest that any ternary expression be enclosed in parentheses (curved brackets). At present you are essentially asking AutoIt to read your mind when you omit the parentheses and expecting it to decide that it should evaluate the ternary expression before using the result as an array index - using the parentheses forces the interpreter to evaluate the ternary first and so everything works as you expect. To my mind this is not a bug, but an example of poor coding syntax on your part which is not picked up by the interpreter - you cannot expect it to manage every edge case that a human coder can produce. M23 TheDcoder 1 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
TheDcoder Posted July 7, 2018 Author Share Posted July 7, 2018 Thank you for the reply @Melba23, I am afraid I would have to disagree with you, while it is true that the help file suggests wrapping a ternary expression in brackets, that doesn't mean it should be required, especially when there are no other operators in the expression. 10 minutes ago, Melba23 said: At present you are essentially asking AutoIt to read your mind when you omit the parentheses and expecting it to decide that it should evaluate the ternary expression before using the result as an array index I would hardly classify evaluating the expression and using the result as the value "reading your mind". I absolutely see no room ambiguity or any other interpretations, only a single operator is used in this case. 20 minutes ago, Melba23 said: To my mind this is not a bug, but an example of poor coding syntax on your part Please do enlighten me, why is this considered poor coding syntax? I don't think it is better to wrap an expression with a single operator in brackets. 26 minutes ago, Melba23 said: you cannot expect it to manage every edge case that a human coder can produce. I agree that it should not be expected to manage every edge case but I would not call it an edge case as it is quite logical to think that an expression should be evaluated before it is used. EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
LarsJ Posted July 7, 2018 Share Posted July 7, 2018 Local $aArray = ["Foo", "Bar", "Baz"] Local $aArray2 = [0, 1, 2] ; Works ConsoleWrite($aArray[$aArray2[1]] & @CRLF) ; Works ConsoleWrite($aArray[(1?1:2)] & @CRLF) ; Doesn't work ConsoleWrite($aArray[1?1:2] & @CRLF) TheDcoder 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
TheDcoder Posted July 7, 2018 Author Share Posted July 7, 2018 (edited) Thanks @LarsJ, the bug only happens if there is a ternary operator it seems. It is interesting because the interpreter still claims that the brackets are unbalanced even if there is only a single pair of them in the statement, maybe the code which handles ternary operator is at fault. Edited July 7, 2018 by TheDcoder EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
LarsJ Posted July 7, 2018 Share Posted July 7, 2018 ... without parentheses Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
TheDcoder Posted July 7, 2018 Author Share Posted July 7, 2018 Sorry, yes, you are correct. I made an edit to mention that EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
LarsJ Posted July 7, 2018 Share Posted July 7, 2018 The ternary operator is probably implemented to be used as an assignment operator this way: $i = 2 $j = $i = 1 ? 0 : 2 If there is no assignment you need the paranthesis: $aArray = ["Foo", "Bar", "Baz"] ConsoleWrite($aArray[( $i = 1 ? 0 : 2 )] & @CRLF) Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
TheDcoder Posted July 7, 2018 Author Share Posted July 7, 2018 I am not sure, this works and there is no assignment going on: ; Works ConsoleWrite(1?1:2 & @CRLF) EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
jchd Posted July 7, 2018 Share Posted July 7, 2018 I wild-guess it's a matter of operator priority. Note that AFAIK this (relatively new) ternary op isn't yet listed in help under priority list. I'd also classify that as minor bug, or at least misfeature. TheDcoder 1 This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
TheDcoder Posted July 7, 2018 Author Share Posted July 7, 2018 My thoughts exactly @jchd EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted July 8, 2018 Moderators Share Posted July 8, 2018 The Dcoder, Quote I absolutely see no room ambiguity or any other interpretations Really? Let us look at the code: ConsoleWrite($aArray[$aArray[0] = "Foo" ? 1 : 2] & @CRLF) ; The ConsoleWrite is fine, so we get $aArray[$aArray[0] = "Foo" ? 1 : 2] ; Now AutoIt looks at this code - there are no parentheses to force prior evaluation so it proceeds linearly ; It sees an array element with the content of another array element as index - no problems there ; but then it sees an assignment operator and so thinks you want assign a value to that array element ; But you have not closed the array element definition and so you get an error ; Using parentheses to force the ternary expression to be evaluated first removes this ambiguity Thus my remark about "poor coding syntax" - do not expect a computer to always think the way you do, make the priority of the elements within an expression absolutely clear. Another good example is using parentheses to clearly define the scope of a Not operator, which often catches out the unwary. Quote I would not call it an edge case as it is quite logical to think that an expression should be evaluated before it is used I hope the above shows why the interpreter does not do what you think it should - it is actually being quite logical, it is up to you as the coder to clarify your intentions. And given the possible complexity of many ternary expressions, I think expecting AutoIt to recognise every possible case is asking rather too much. There must be a line drawn between looking for obvious errors and having massively bloated code to cover "every" case - which of course will never be completely watertight as humans are far too ingenious! So I reiterate my opinion that this is not a bug but an example of poor coding syntax where what appears logical to the coder is not actually seen as such by the interpreter. It is up to the coder to make his intentions clear - and using parentheses to force prior evaluation is a good example. As a matter of fact I always enclose the separate elements of a ternary expression in parentheses as well, so my version would read: ConsoleWrite($aArray[(($aArray[0] = "Foo") ? (1) : (2))] & @CRLF) M23 JLogan3o13 1 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
jchd Posted July 8, 2018 Share Posted July 8, 2018 I beg to differ. In the case at hand the bold red part is an expression which must be evaluated like any other expression (this fails): ConsoleWrite($aArray[$aArray[0] = "Foo" ? 1 : 2] & @CRLF) but this bold red expression is correctly interpreted in a different context (this works): ConsoleWrite($aArray[0] = "Foo" ? 1 : 2) ConsoleWrite(@CRLF) If the interpretor would interpret $aArray[0] = "Foo" separately, it wouldn't see an assignment but an equality test (which the first part of a ternary actually is). And indeed this is what happens in (works): ConsoleWrite($aArray[$aArray[0] = "Foo"] & @CRLF) The result of such a test is (here) the boolean True, so the inirial bold red expression would then become ConsoleWrite($aArray[True ? 1 : 2] & @CRLF) But this bold now green expression isn't evaluated correctly either in this context. Yet the same expression is correctly evaluated in another context: ConsoleWrite(True ? 1 : 2) ConsoleWrite(@CRLF) Hopefully AutoIt is meant to have an almost context-free grammar (we have no == operator) but this example demonstrates that <expr> isn't parsed the same in Function(<expr>) and Function($a[<expr>]) This is why I stand behind my statement that it's a bug. I called it minor because it's dead easy to work around, but bugs in expression parsers are fundamental to any language. A parser MUST be consistent and psychorigid. The advice in help to enclose ternary expressions in () arose mostly because newbies tend to write things like ConsoleWrite($x = "Three" ? 3 : 0 & @CRLF) and be surprised by the outcome. TheDcoder 1 This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
TheDcoder Posted July 8, 2018 Author Share Posted July 8, 2018 Hello Melba, I agree that using parentheses is a good practice and it certainly helps the interperter know what is in your mind. And you are indeed correct about it "linearly" evaluating the expression and mistaking the = operator for being used for assignment this code proves it: Local $aArray = ["Foo", "Bar", "Baz"] ; Works (no equal operator) ConsoleWrite($aArray[$aArray[0] <> "Foo" ? 1 : 2] & @CRLF) ; Doesn't work ConsoleWrite($aArray[$aArray[0] = "Foo" ? 1 : 2] & @CRLF) ConsoleWrite($aArray[$aArray[0] == "Foo" ? 1 : 2] & @CRLF) As I was writing my reply, @jchd came up with exactly what I was trying to demonstrate. Kudos and thanks This would only require correcting the context in which the expressions are evaluated inside the square brackets of an array, so that = doesn't get mistaken. 8 minutes ago, jchd said: (we have no == operator) Small correction: We do have that, it is the case-sensitive comparision operator , but as I have demonstrated in my code above, it still doesn't work. EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
jchd Posted July 8, 2018 Share Posted July 8, 2018 I meant that = is double-headed in AutoIt and was refering to C/C++ or other == 5 minutes ago, TheDcoder said: This would only require correcting the context in which the expressions are evaluated inside the square brackets of an array, so that = doesn't get mistaken. The parser isn't confused by = as this show (fails too) ConsoleWrite($aArray[1 ? 1 : 2]) TheDcoder 1 This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
TheDcoder Posted July 8, 2018 Author Share Posted July 8, 2018 I didn't notice that at all! Very surprising and interesting... I am not sure what is going wrong in this case, and I reckon we cannot test furthur as we cannot remove the remaining symbols in the expression. I have to change the title yet again... maybe I should make it more generic. EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now