InunoTaishou

Why does a string used in an expression return 0?

36 posts in this topic

#1 ·  Posted

I know on other languages when you try to use a string like this

Global $sString = "Some String"

If ($sString) Then
    ; ...
EndIf

The compiler will fail because string cannot be used in an expression where it needs a bool (something along those lines). But I see instances in other languages where using $sString in an expression will work and implicitly use the length of the string (or because there is some value in that variable).

I'm wondering why AutoIt doesn't do the same. If the $sString is used like in my example (or some other expression where it wants a bool type) implicitly use the length of the string instead of the converting to 0?

Share this post


Link to post
Share on other sites



#2 ·  Posted

Isn't that what the _IsString(), _IsDeclared(), StringLen() functions are for?  From my logic:

If "Some String" Then ... doesn't really mean anything or maybe my logic is just screwed up :) 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

But AutoIt implicitly converts any string used in an expression where it wants a true/false to 0 if that string is not a string representation of a number or true/false ("True" or "False"). If it's going to do that why not implicitly convert it to 1 if the string is not "" (empty/null string)?

IsString just checks if the variable is a string (I.e., 32 is not a string but "32" is)

_IsDeclared just checks if the string representation of the variable is declared in the script

and StringLen is what would be used currently

This is how we currently do it

Global $sString = "Some String"

While (StringLen($sString))
    ConsoleWrite($sString & @LF)
    $sString = StringTrimLeft($sString, 1)
WEnd

And this is how we could be doing it

Global $sString = "Some String"

While ($sString)
    ConsoleWrite($sString & @LF)
    $sString = StringTrimLeft($sString, 1)
WEnd

Seems like such an insignificant thing but it's surprisingly useful. I went from C++, VB, AutoIt to Python (where the latter does work) and it's so freaking nice being able to use the string as a boolean in an if statement

Edited by InunoTaishou

Share this post


Link to post
Share on other sites

#4 ·  Posted

I used to do that all over the place and am still correcting it when I see it :D

It seems a bit silly to have to write ...

If $sTring <> "" Then

If isEmpty($sTring) Then ... (in some languages)

But I guess there may be good reasons for it...
It's why it's good to first start studying the basics before you start tinkering. I'm still telling myself that every day... ;)

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

It was an illogical decision IMO. I believe you should be able to use strings in boolean expressions. Actually it seems to be working. Which version of AutoIt are you using?

Edited by czardas

Share this post


Link to post
Share on other sites

#6 ·  Posted

I just ran

Global $sString = "Some String"

While ($sString)
    ConsoleWrite($sString & @LF)
    $sString = StringTrimLeft($sString, 1)
WEnd

And it actually worked.... I don't know who did it, I don't know when it happened, but I swear this used to not work.... Strings used to always evaluate to 0 when used in a boolean expression.

Does this work for anyone else?

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

We are mistaking it for something else. This works for me.

If 'some string' Then MsgBox(0, '', 'hey')


Conversion of string to number is the oddball.

MsgBox(0, '', Number('3v')) ; converts to 3

I find that so illogical.

Edited by czardas

Share this post


Link to post
Share on other sites

#8 ·  Posted

I remember very specifically that it didn't used to work, and was very frustrated by this. Looking back at a few old scripts I had to use things like Stringlen and Not $sString == ""

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Maybe it was like that previously. I don't remember.

Edited by czardas

Share this post


Link to post
Share on other sites

#10 ·  Posted

strings still evaluate to 0 in some cases, no?

msgbox("some string" , "some string" , "some string")

 


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

3 hours ago, iamtheky said:

strings still evaluate to 0 in some cases, no?

Could be two different things. A boolean comparison verses a default error override. I don't know.

Edited by czardas

Share this post


Link to post
Share on other sites

#12 ·  Posted

maybe?

#include<array.au3>

local $aArray["zero elements please"]
_ArrayDisplay($aArray , ubound($aArray))

 


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

Of course you should never rely on undocumented behaviour.

#include<array.au3>

local $aArray["3 elements please"]
_ArrayDisplay($aArray , ubound($aArray))

In this case it certainly appears to be a conversion.

In addition: boolean comparisons between different data types may sometimes lead to (apparently) contradictory results.

Edit: This is also a conversion, and not the result of some default override value.

MsgBox('1 or 2', '', 'meh')

 

Edited by czardas

Share this post


Link to post
Share on other sites

#14 ·  Posted

There is no more "contradictory results" than "some cases" or "random conversion behavior".

Well written computer programs are pretty bad at creating non-repeatable surprising behavior, contrary to humans. Instead, they hopefully exhibit very deterministic behavior which we all rely upon, else our lives would turn turmoil.

A string evaluates to its content when used in a string expression (or parameter of a function expecting a string). No surprise here.

It evaluates to a boolean in a boolean context: Flase if the string is empty, True if non-empty.

It evaluates to its numeric conversion (using Number()) when in a numeric context. Here an empty string evaluates to 0.

All of this always behaved the same for decade(s) AFAICT.

1 person likes this

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 here
RegExp tutorial: enough to get started
PCRE 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)

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

I have shown two cases where a non-empty (or empty) string evaluates to 0, I could understand that being a product of the msgbox function, but the behavior exists with declaring arrays as well.  And that behavior has existed as long as I have been trolling threads regarding magic numbers.

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

#16 ·  Posted

An dimension index is expected to be numeric, so Number is applied to the string, yielding zero. No surprise here either.


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 here
RegExp tutorial: enough to get started
PCRE 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)

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

so this would be an expected solution if I needed arrays from a list?  because formatting seems like an extra rather than necessary step if the behavior is expected, but I never see it in action.

#include<array.au3>

$sList1 = "20 bottles"
$sList2 = "45 plates"
$sList3 = "200 cups"

local $aArray1[$sList1]
local $aArray2[$sList2]
local $aArray3[$sList3]

_ArrayDisplay($aArray1)
_ArrayDisplay($aArray2)
_ArrayDisplay($aArray3)

 

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

#18 ·  Posted

I don't believe the interpretor would get mad at you if you use that, albeit that useage might surprise future maintainers.


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 here
RegExp tutorial: enough to get started
PCRE 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)

Share this post


Link to post
Share on other sites

#19 ·  Posted

It's like we've had a breakthrough! Lol (Sorry I'm late, was busy yesterday)

I quite like the

#include<array.au3>

$sList1 = "20 bottles"
$sList2 = "45 plates"
$sList3 = "200 cups"

local $aArray1[$sList1]
local $aArray2[$sList2]
local $aArray3[$sList3]

_ArrayDisplay($aArray1)
_ArrayDisplay($aArray2)
_ArrayDisplay($aArray3)

Then you could give self documenting arrays self documenting values

#include<array.au3>

Global $aBeers["10 draught beers"]
$aBeers["0 Coors"] = "Coors"
$aBeers["1 Fosters"] = "Fosters"
$aBeers["2 Staropramen"] = "Staropramen"
$aBeers["3 Personi"] = "Personi"
$aBeers["4 Fuller’s London Pride"] = "Fuller’s London Pride"
$aBeers["5 Cruzcampo"] = "Cruzcampo"
$aBeers["6 Heineken"] = "Heineken"
$aBeers["7 San Miguel"] = "San Miguel"
$aBeers["8 Stella Artois"] = "Stella Artois"
$aBeers["9 Mockingfish"] = "Mockingfish"

_ArrayDisplay($aBeers)

(I don't drink, beer was just something that came to mind)

1 person likes this

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

I said '(apparently) contradictory' results. Anyway, I don't like the numeric conversion of strings (current implementation) because it doesn't differentiate between valid and invalid numbers. The loose conversion is a bit too loose IMO.

Edited by czardas

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

  • Similar Content

    • Eli_jahbot
      By Eli_jahbot
      my esteemed autoits,
      i need your help once again. The bold and italics below are what i will be referring to. I need a message box to exit the script if Cancel is pressed and to continue the script if OK is pressed. I have tried multiple ways to do this to no avail. Can someone please breakdown how i go about this via Message box, and or Input box as I'm sure they will follow the same logic. I appreciate your time and assistance.
       
      Example:
      global $url, $username, $password, $sspassword
      $url = "https://securegateway.fairview.org"
      $username = "XXX"
      $password = "YYY"
      $sspassword = "ZZZ"
      #include <Constants.au3>
      #include <msgboxconstants.au3>
      ShellExecute ($url)
      WinWaitActive("window")
      send($username)
      send("{tab}")
      send($password)
      send("{enter}")
      msgbox($mb_okcancel, "Wait for the page to load then select OK to continue script", "Wait for the page to load then select OK to continue script")
      if($idok)
      send("+{tab 8}")
      send("{enter}")
      if ($idcancel) then Exit
      EndIf
    • cheeroke
      By cheeroke
      Hi all,
      I got this code and would like to be able to change Baud Rate and instead of sending character by character i would like to be able (if possible) to send whole string. But i don't know how to change it.
      I am taking input from file and processing whole line (this is done in FilesHandling.au3).
      To execute this i am just calling SendData("FileName", int) in "main" script.
      Any help very appreciated.
      #include <WinAPI.au3> #include <Array.au3> #include "FilesHandling.au3" ;init DLL function, we need handle to call the function $h = DllCall("Kernel32.dll", "hwnd", "CreateFile", "str", "\\.\COM19", "int", BitOR($GENERIC_READ,$GENERIC_WRITE), "int", 0, "ptr", 0, "int", $OPEN_EXISTING, "int", $FILE_ATTRIBUTE_NORMAL, "int", 0) $handle=$h[0] Func SendData($FileName, $LineNumber) ;string to be send $c = readFile($FileName, $LineNumber) $cLenght = StringLen($c) $aArray = StringSplit($c, "") ;_ArrayDisplay($aArray, "", Default, 64) For $i = 1 To $cLenght writeChar($handle, $aArray[$i], $cLenght) Next ;move to next line writeChar($handle, @CR,1) EndFunc ;write a single char func writeChar($handle,$c,) $stString = DLLStructCreate("char str") $lpNumberOfBytesWritten = 0 DllStructSetData($stString, 1, $c) $res = _WinAPI_WriteFile($handle, DllStructGetPtr($stString, "str"), 1,$lpNumberOfBytesWritten) if ($res<>true) then ConsoleWrite ( _WinAPI_GetLastErrorMessage() & @LF) EndIf EndFunc  
    • FroVN
      By FroVN
      Hi, i have a problem :" can't set the name of file with a special character like: \;/;";|;...  have anyway to short the StringInSrt and Stringreplace? i am using this code but too long
      $title=InputBox(0,'','','')
         if StringInStr($title,'\') or StringInStr($title,'/') or StringInStr($title,':') or StringInStr($title,'*') or StringInStr($title,'?') or StringInStr($title,'"') or StringInStr($title,'<') or StringInStr($title,'>') or StringInStr($title,'|') Then
             $title=StringReplace($title,'\','-')
              $title=StringReplace($title,'/','-')
               $title=StringReplace($title,':','-')
                $title=StringReplace($title,'*','-')
                 $title=StringReplace($title,'?','-')
                  $title=StringReplace($title,'"','-')
                   $title=StringReplace($title,'<','-')
                    $title=StringReplace($title,'>','-')
                     $title=StringReplace($title,'|','-')
         EndIf
       
    • JustinZandee
      By JustinZandee
      I need a random string generator which creates 15 letters/numbers.
      How can I make that?
    • anthonyjr2
      By anthonyjr2
      Hi guys,
      I am pretty bad with regex, and am having some trouble trying to come up with an expression for a certain type of string. Basically I want to be able to tell if a string is of the format:
      AA#####A
      Where the A's are any letter from A-Z and the #'s are any digit from 0-9.
      I've been playing around with a regex tester online for a while but I can't really seem to grasp the concept very well. Could anyone give me any tips?
      This isn't exactly an AutoIt specific question which is why I didn't post it in General Help & Support.