Sign in to follow this  
Followers 0
misterioes

= operator and its strange behaviour

7 posts in this topic

#1 ·  Posted (edited)

I want to share something really odd that just happened to me, what I can't understand at all. Maybe someone can shed a light on this for me.

Now, in autoit it is possible to compare variables via "=" in If statements. That works most of the time it seems, but not always.

Take a look at this code:

MsgBox(0, "", IniRead($iniPath, "Settings", "autostart", "False")) ; output: "False"
    If IniRead($iniPath, "Settings", "autostart", "False") = True Then
        GUICtrlSetState($OptionsCustomID, $GUI_CHECKED) ; this line gets processed
    Else
        GUICtrlSetState($OptionsCustomID, $GUI_UNCHECKED)
    EndIf

MsgBox(0, "", IniRead($iniPath, "Settings", "autostart", "False")) ; output: "False"
    If False = True Then
        GUICtrlSetState($OptionsCustomID, $GUI_CHECKED)
    Else
        GUICtrlSetState($OptionsCustomID, $GUI_UNCHECKED) ; this line gets processed
    EndIf

However, if I compare in C - Style ...

MsgBox(0, "", IniRead($iniPath, "Settings", "autostart", "False")) ; output: "False"
    If IniRead($iniPath, "Settings", "autostart", "False") == True Then
        GUICtrlSetState($OptionsCustomID, $GUI_CHECKED) 
    Else
        GUICtrlSetState($OptionsCustomID, $GUI_UNCHECKED) ; this line gets processed
    EndIf

... it works as expected

How is that possible ?

Edited by misterioes

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Looks like more of an issue with iniRead.

MsgBox (0, "", IniRead($iniPath, "Settings", "autostart", "False")) ; output: False
MsgBox (0, "", Not IniRead($iniPath, "Settings", "autostart", "False")) ; output: False

Wait, what?

This is mind-boggling...

Edited by misterioes

Share this post


Link to post
Share on other sites

misterioes,

How is that possible ?

Because you are comparing different things. :)

In your first example you are retrieving a string from the ini file - which happens to read "True" or "False". This is very different from a variable which holds the Boolean value of True or False.

In you second example you are comparing 2 Boolean values

If you use the standard AutoIt = operator, AutoIt must decide what type of variable you want to compare. Here are the results I get - and the explanations of why I get them:

ConsoleWrite("True" & @CRLF)

$fFlag_String = "True"

$fFlag_Bool = True

If $fFlag_String = True Then ConsoleWrite("String - Bool = True" & @CRLF)       
; Appears because the string exists and so is True in the Boolean sense

If $fFlag_Bool = True Then ConsoleWrite("Bool - Bool = True" & @CRLF)
; Appears becasue both are Boolean

If $fFlag_String = "True" Then ConsoleWrite("String - String = True" & @CRLF)    
; Appears because both are strings

If $fFlag_Bool = "True" Then ConsoleWrite("Bool - String = True" & @CRLF)
; Appears because AutoIt decides you must want to comapre string and so converts the Boolean into a string


ConsoleWrite(@CRLF & "False" & @CRLF)

$fFlag_String = "False"

$fFlag_Bool = False

If $fFlag_String = True Then ConsoleWrite("String - Bool = True" & @CRLF)
; Appears because the string exists and so is True in the Boolean sense

If $fFlag_Bool = True Then ConsoleWrite("Bool - Bool = True" & @CRLF)
; Does NOT appear becaue the 2 Boolean values are not the same

If $fFlag_String = "True" Then ConsoleWrite("String - String = True" & @CRLF)
; Does NOT appear because the 2 string values are not the same

If $fFlag_Bool = "True" Then ConsoleWrite("Bool - String = True" & @CRLF)
; Does NOT appear because the converted Boolean does not match the string

Only a Null string ("") is False in the Boolean sense - similarly only 0 is Boolean False when dealing with numbers.

When you use the == operator, as in your third example, this forces AutoIt to use a case-sensitive string comparison - so the Boolean is converted and compared with the same results as the Bool - String comparisons above.

This is all because Autoit does not use typed varables and has to make assumptions as to what type you want to use. That is why there are KeyWords such as Number, String, Int, Ptr, HWnd, etc - sometimes you need to be explicit. But the flexibility you get by not having typed variables is such that most of us accept the odd occasion where you do need to be careful. :P

Does that make sense now? Please ask again if not. :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Now, in autoit it is possible to compare variables via "=" in If statements. That works most of the time it seems, but not always.

In your first example you are comparing an string to a boolean so "False" will always be true.

In your second script you are comparing two booleans so it is fine, boolean False is not equal to boolean True.

Third script, using == you are converting both parameters to strings so False is not True.

Edit: As usual, Melba23 is faster... and he gave you a very good explanation :)

Edited by sahsanu

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Thank you very much, I understand my mistake now :)

Quite embarrassing mistake.

and yeah, very well elaborated :)

Edited by misterioes

Share this post


Link to post
Share on other sites

misterioes,

Not embarrassing at all. :)

It takes a while to get used to having only Variant variables but as I pointed out above, in the opinion of most users, the flexibility gained is well worth the occasional use of a type definition.

Glad you got it straight. :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

When using IniRead to get a boolean value, you should do something like that:

$bool = _Bool(IniRead(...))
Func _Bool($vBool)
    ; ProgAndy
    If IsBool($vBool) Then Return $vBool
    If IsNumber($vBool) Or StringIsDigit($vBool) Or Return Number($vBool) <> 0
    If IsPtr($vBool) Return $vBool <> Ptr(0)
    Switch $vBool
        Case "yes", "true", "y", "j", "ja", "wahr"
            Return True
        Case Else
            Return False
    EndSwitch
EndFunc
Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0