Sign in to follow this  
Followers 0
Dana

Variant, string, and number

10 posts in this topic

I'm trying to understand how AutoIt treats variables. I understand that everything is a variant, and that comparisons (< or >) treat a variable as a string even if the data is numeric (which is what was confusing me, as it has confused others before). In the case of my script, I learned I can solve the problem either by using Number() or multiplying the variable by 1. I understand that using either technique to convert the string into a number makes the comparison work properly.

I can see that using Number($var) or $var*1 as input to the comparison should work. What I don't understand is why it also works if I do the conversion earlier and store that result in a new variable (in this case an element of an array). Once the numeric data is stored in a new variable, which again is a variant, how does AutoIt know later that it's still a number and not a string?

I understand why this doesn't work (returns false):

$line1 = "<ele>99.511963</ele>"
$ele1 = StringMid($line1, (StringInStr($line1, '<ele>') + 5), StringInStr($line1, '</ele>') - (StringInStr($line1, '<ele>') + 5))
$line2 = "<ele>125.511963</ele>"
$ele2 = StringMid($line2, (StringInStr($line2, '<ele>') + 5), StringInStr($line2, '</ele>') - (StringInStr($line2, '<ele>') + 5))
ConsoleWrite($ele2 > $ele1)

I understand why this does work (returns true):

$line1 = "<ele>99.511963</ele>"
$ele1 = StringMid($line1, (StringInStr($line1, '<ele>') + 5), StringInStr($line1, '</ele>') - (StringInStr($line1, '<ele>') + 5))
$line2 = "<ele>125.511963</ele>"
$ele2 = StringMid($line2, (StringInStr($line2, '<ele>') + 5), StringInStr($line2, '</ele>') - (StringInStr($line2, '<ele>') + 5))
ConsoleWrite(Number($ele2) > Number($ele1))

I understand [i think] why this works (returns true):

$line1 = "<ele>99.511963</ele>"
$ele1 = StringMid($line1, (StringInStr($line1, '<ele>') + 5), StringInStr($line1, '</ele>') - (StringInStr($line1, '<ele>') + 5))
$line2 = "<ele>125.511963</ele>"
$ele2 = StringMid($line2, (StringInStr($line2, '<ele>') + 5), StringInStr($line2, '</ele>') - (StringInStr($line2, '<ele>') + 5))
ConsoleWrite($ele2*1 > $ele1*1)

I'm not sure why this works (returns true)... once one of the values being compared is a number does AutoIt treat both as numbers?:

$line1 = "<ele>99.511963</ele>"
$ele1 = StringMid($line1, (StringInStr($line1, '<ele>') + 5), StringInStr($line1, '</ele>') - (StringInStr($line1, '<ele>') + 5))
$line2 = "<ele>125.511963</ele>"
$ele2 = StringMid($line2, (StringInStr($line2, '<ele>') + 5), StringInStr($line2, '</ele>') - (StringInStr($line2, '<ele>') + 5))
ConsoleWrite(Number($ele2) > $ele1)

Using "*1" instead of Number() on just one of the numbers also works.

I don't understand why this works:

$line1 = "<ele>99.511963</ele>"
$ele1 = Number(StringMid($line1, (StringInStr($line1, '<ele>') + 5), StringInStr($line1, '</ele>') - (StringInStr($line1, '<ele>') + 5)))
$line2 = "<ele>125.511963</ele>"
$ele2 = StringMid($line2, (StringInStr($line2, '<ele>') + 5), StringInStr($line2, '</ele>') - (StringInStr($line2, '<ele>') + 5))
ConsoleWrite($ele2 > $ele1)

In this one, the Number() function makes the string into a number, but then it's stuffed into $ele1, which is again a variant... so why does the last line still treat it as a number and not a string?

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

... and that comparisons (< or >) treat a variable as a string even if the data is numeric ...

I think this assumption is wrong. AutoIt treats a string as a string when it's a string.

So "a" < "b" is a string comparison but 3 < 4 is a numeric comparison. You only run into problems when a function you call returns a string (like FileRead) but you assume it's numeric. When a variable has been transformed from string to numeric it stays numeric until it is transformed to string again.

That's how I understand it - but I could be wrong :D

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Variant is a term that describes a containers ability to hold multiple types (string, integer etc.). If this should work without undefined behaviour, the container needs to keep track of its own type - which it does, ofcourse.

An autoit variable is a variant, that knows its own type. it can be changed on the fly, and comparison + math operations differs in behaviour depending on the type used. You can read this: http://www.autoitscript.com/autoit3/docs/intro/lang_datatypes.htm


Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Share this post


Link to post
Share on other sites

That describes it much better than I could ever have done (pitty not being a native speaker)


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

... the container needs to keep track of its own type..... it can be changed on the fly...

Thanks, that makes sense... there's more information in a variant than the visible data itself.

So ConsoleWrite("2" + "2") returns 4 even though it's being fed two strings, changing them on the fly because of the "+" operator, and ConsoleWrite(2 & 2) returns 22 because of the "&" operator... and only the greater than / less than operators are ambiguous (not really, but the supplied value needs to be unambiguous):

> Tests if the first value is greater than the second. Strings are compared lexicographically even if the contents of the string happen to be numeric.

As water said, I ran into trouble because my input string $line came from a FileRead operation and stayed a string through the string manipulations in the second line of my examples. I didn't have this problem elsewhere because other numbers I read in from the file had strictly numeric math operations performed on them rather than comparisons.

I guess it's good practice to use the Number() function on any numeric data read in from a file, or subject to string manipulation.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Although using Number() should always work, I still think it's best to check what happens with different types of function. Sometimes you can omit Number() , since the conversion will take place within the function you are calling. You want to avoid unnecessary duplication of arguments.

water, I never would have guessed your native langage was not English. :D

Edited by czardas

Share this post


Link to post
Share on other sites

water, I never would have guessed your native langage was not English. :D

Read tons of his comments and never once would have thought. Makes me wonder what his natural tongue is.


A true renaissance man

Share this post


Link to post
Share on other sites

Read tons of his comments and never once would have thought. Makes me wonder what his natural tongue is.

Mmm.. His sig says Austria so my educated guess would be a sort of German variation. :D

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

"Sort of German variation" hits the nail on the head :D


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

water, I never would have guessed your native langage was not English. :oops:

Hi Czardas,

thanks for this complement! I'm glad that this is not a french forum :D


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

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