Search the Community
Showing results for tags 'anonymous methods'.
-
If you are coming from the realm of C# 3.0 then lamda expressions should be pretty familiar to you as it's basic syntactic sugar for creating a function with a conditional return. Since functions in AutoIt are first class objects, the following code should make some sense. It passes an array of integers to a function called IsTrueForAll() that checks whether the function object matches the return condition of that function (you passed). So for example a function called IsGreaterThanOrEqualTo10() checks if all values are greater than or equal to 10 (TRUE). Similarly, IsLessThan10() checks if all values are less than 10 (FALSE). This example should be nothing new to those of you who use v3.3.10.0+ and have an understanding of Call(). #include <MsgBoxConstants.au3> Local $aArray[] = [10, 100, 99, 67] If IsTrueForAll($aArray, IsGreaterThanOrEqualTo10) Then MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.') Else MsgBox($MB_SYSTEMMODAL, '', 'Condition was False') EndIf If IsTrueForAll($aArray, IsLessThan10) Then MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.') Else MsgBox($MB_SYSTEMMODAL, '', 'Condition was False') EndIf Func IsTrueForAll($aArray, $hFunc) ; Loop through the array and check the function passed with a single param matches the condition. For $i = 0 To UBound($aArray) - 1 If Not $hFunc($aArray[$i]) Then Return False EndIf Next Return True EndFunc ;==>IsTrueForAll Func IsGreaterThanOrEqualTo10($x) Return $x >= 10 EndFunc ;==>IsGreaterThanOrEqualTo10 Func IsLessThan10($x) Return $x < 10 EndFunc ;==>IsLessThan10 But, we could easily just forget about writing the functions (less typing is always nice) and let the compiler or pre-processor do all the work for us. It would simply use the lambda expression and create the function for us with whatever we specified. Like so... #include <MsgBoxConstants.au3> Local $aArray[] = [10, 100, 99, 67] If IsTrueForAll($aArray, $x => $x >= 10) Then ; $x is the parameter, => tells us it's a lambda expression and then the condition we are checking. MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.') Else MsgBox($MB_SYSTEMMODAL, '', 'Condition was False') EndIf If IsTrueForAll($aArray, $x => $x < 10) Then ; $x is the parameter, => tells us it's a lambda expression and then the condition we are checking. MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.') Else MsgBox($MB_SYSTEMMODAL, '', 'Condition was False') EndIf Func IsTrueForAll($aArray, $hFunc) ; Loop through the array and check the function passed with a single param matches the condition. For $i = 0 To UBound($aArray) - 1 If Not $hFunc($aArray[$i]) Then Return False EndIf Next Return True EndFunc ;==>IsTrueForAll...which would create the following code with anonymous functions (they're anonymous as we don't care about them in our main script)... #include <MsgBoxConstants.au3> Local $aArray[] = [10, 100, 99, 67] If IsTrueForAll($aArray, D3F7B1B92177415CA70C7FFC35C2649C) Then MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.') Else MsgBox($MB_SYSTEMMODAL, '', 'Condition was False') EndIf If IsTrueForAll($aArray, DA06B548ABF4045AA32F805E6651004) Then MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.') Else MsgBox($MB_SYSTEMMODAL, '', 'Condition was False') EndIf Func IsTrueForAll($aArray, $hFunc) For $i = 0 To UBound($aArray) - 1 If Not $hFunc($aArray[$i]) Then Return False EndIf Next Return True EndFunc ;==>IsTrueForAll Func D3F7B1B92177415CA70C7FFC35C2649C($x) Return $x >= 10 EndFunc ;==>D3F7B1B92177415CA70C7FFC35C2649C Func DA06B548ABF4045AA32F805E6651004($x) Return $x < 10 EndFunc ;==>DA06B548ABF4045AA32F805E6651004 Example of parsing a lambda expression and replacing in the chosen script: #include <WinAPICom.au3> ; Script read from a file. Local $sScript = "#include <MsgBoxConstants.au3>" & @CRLF $sScript &= "" & @CRLF $sScript &= "Local $aArray[] = [10, 100, 99, 67]" & @CRLF $sScript &= "If IsTrueForAll($aArray, $x => $x >= 10) Then" & @CRLF ; Lambda expression. $sScript &= " MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.')" & @CRLF $sScript &= "Else" & @CRLF $sScript &= " MsgBox($MB_SYSTEMMODAL, '', 'Condition was False')" & @CRLF $sScript &= "EndIf" & @CRLF $sScript &= "" & @CRLF $sScript &= "If IsTrueForAll($aArray, $x => $x < 10) Then" & @CRLF ; Lambda expression. $sScript &= " MsgBox($MB_SYSTEMMODAL, '', 'Condition was True.')" & @CRLF $sScript &= "Else" & @CRLF $sScript &= " MsgBox($MB_SYSTEMMODAL, '', 'Condition was False')" & @CRLF $sScript &= "EndIf" & @CRLF $sScript &= "" & @CRLF $sScript &= "Func IsTrueForAll($aArray, $hFunc) ; Loop through the array and check the function passed with a single param matches the condition." & @CRLF $sScript &= " For $i = 0 To UBound($aArray) - 1" & @CRLF $sScript &= " If Not $hFunc($aArray[$i]) Then" & @CRLF $sScript &= " Return False" & @CRLF $sScript &= " EndIf" & @CRLF $sScript &= " Next" & @CRLF $sScript &= " Return True" & @CRLF $sScript &= "EndFunc ;==>IsTrueForAll" & @CRLF ReplaceLambdaInScript($sScript, '$x => $x >= 10') ; Parse the lambda expression and replace it in the above script. ReplaceLambdaInScript($sScript, '$x => $x < 10') ; Parse the lambda expression and replace it in the above script. ConsoleWrite($sScript & @CRLF) ; This is the new script with the lamda expression convert to an anonymous method! ClipPut($sScript) Func CreateLambdaMethod($sExpression) ; Currently no error checking of whether parameters match. Local $bIsReturn = False, _ ; Is the return condition. $sFunction = StringRegExpReplace(_WinAPI_CreateGUID(), '[}{-]', ''), $sParam = '', $sReturn = '' $sFunction = StringRegExpReplace($sFunction, '^\d+', '') ; Remove digits at the beginning of the function name. For $i = 1 To StringLen($sExpression) $sChr = StringMid($sExpression, $i, 1) If $bIsReturn Then $sReturn &= $sChr ElseIf $sChr & StringMid($sExpression, $i + 1, 1) == '=>' Then ; Check for => $i += 1 $bIsReturn = True ElseIf Not $bIsReturn Then $sParam &= $sChr EndIf Next If Not $bIsReturn Then Return "" ; Something went wrong as the => was not found. $sParam = '(' & StringRegExpReplace($sParam, '^\h*|\h*$', '') & ')' $sReturn = @TAB & 'Return ' & $sReturn Return 'Func ' & $sFunction & $sParam & @CRLF & $sReturn & @CRLF & 'EndFunc ;==>' & $sFunction & @CRLF EndFunc ;==>CreateLambdaMethod Func ReplaceLambdaInScript(ByRef $sScript, $sLambda) Local $sFunction = CreateLambdaMethod($sLambda) Local $sFunctionName = StringRegExp($sFunction, 'Func (\w*)\(', 3) If @error Then Return False $sFunctionName = $sFunctionName[0] $sScript = StringReplace($sScript, $sLambda, $sFunctionName, 1) $sScript &= @CRLF & $sFunction Return True EndFunc ;==>ReplaceLambdaInScriptIt was a simple idea I had this morning whilst having breakfast.