Sign in to follow this  
Followers 0
DTNGUYEN

Print out a variable name

22 posts in this topic

Do you know if AutoIt support any function to print out or to get a variable name.

Example: GetVarName($strABCD) will return a string "$strABCD"

Share this post


Link to post
Share on other sites



MsgBox(0, "", "Variable $strABCD contains " & $strABCD)

A variable's name is ... its name! What else do you want?


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

For example:

Func PrintOut($varName)

ConsoleWrite("$varName = " & $varName)

EndFunc

$strName = "Harry"

$intAge = 35

In this case if we call:

PrintOut($strName) --> It will print out $varName = Harry

PrintOut($intAge) --> It will print out $varName = 35

You see, it always prints out "$varName" but not the name of the varialbe.

Actually, I really want to print out:

PrintOut($strName) --> $strName = Harry

PrintOut($intAge) --> $intAge = 35

Share this post


Link to post
Share on other sites

Actually, I really want to print out ... the name of a variable passed as an argument to a function. <-- that's the part you omit !

Pass as arguments to your function: the name of the variable.

$strName = "Harry"

PrintOut('$strName')

Func PrintOut($varName)

ConsoleWrite($varName & ' = ' & Eval($varName) & @LF)

EndFunc


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

Hm..

$strName = "Harry"

PrintOut('$strName')

Func PrintOut($varName)
ConsoleWrite($varName & ' = ' & Eval(StringTrimLeft($varName, 1)) & @LF)
EndFunc

??


Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Share this post


Link to post
Share on other sites

I will support the idea of jchd along with another as 2nd example using ExpandVarStrings option. Used double up of $ for 1st example i.e. $variable$ to ensure string is a more so possible variable name and also be compatible with the ExpandVarStrings option.

$strName = "Harry"

_PrintOutStrVar('$strName$')
_PrintOutEnvVar('$strName$')

Exit

Func _PrintOutStrVar($varName)
    Local $parName
    ; if value of $varName has $ on both ends of string
    If StringLeft($varName, 1) = '$' And StringRight($varName, 1) = '$' Then
        ; remove last $ char in parameter string
        $parName = StringTrimRight($varName, 1)
        ; remove 1st $ char in parameter string and evaluate to get value
        $varName = Eval(StringTrimLeft($parName, 1))
        ConsoleWrite('Variable: ' & $parName & ' = Value: ' & $varName & @LF)
    EndIf
EndFunc

Func _PrintOutEnvVar($varName)
    Local $parName
    ; if value of $varName has $ on both ends of string
    If StringLeft($varName, 1) = '$' And StringRight($varName, 1) = '$' Then
        ; remove last $ char in parameter string
        $parName = StringTrimRight($varName, 1)
        ; enable expansion of variable strings
        Opt('ExpandVarStrings', True)
        ; $varName = '$varName$' (expanded to get value)
        $varName = $varName
        ; disable expansion of variable strings
        Opt('ExpandVarStrings', False)
        ConsoleWrite('Variable: ' & $parName & ' = Value: ' & $varName & @LF)
    EndIf
EndFunc

Output:

Variable: $strName = Value: Harry
Variable: $strName = Value: Harry

:mellow:

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

I will support the idea of jchd along with another as 2nd example using ExpandVarStrings option. Used double up of $ for 1st example i.e. $variable$ to ensure string is a more so possible variable name and also be compatible with the ExpandVarStrings option.

$strName = "Harry"

_PrintOutStrVar('$strName )
_PrintOutEnvVar('$strName )

Exit

Func _PrintOutStrVar($varName)
    Local $parName
    ; if value of $varName has $ on both ends of string
    If StringLeft($varName, 1) = ' And StringRight($varName, 1) = ' Then
        ; remove last $ char in parameter string
        $parName = StringTrimRight($varName, 1)
        ; remove 1st $ char in parameter string and evaluate to get value
        $varName = Eval(StringTrimLeft($parName, 1))
        ConsoleWrite('Variable: ' & $parName & ' = Value: ' & $varName & @LF)
    EndIf
EndFunc

Func _PrintOutEnvVar($varName)
    Local $parName
    ; if value of $varName has $ on both ends of string
    If StringLeft($varName, 1) = ' And StringRight($varName, 1) = ' Then
        ; remove last $ char in parameter string
        $parName = StringTrimRight($varName, 1)
        ; enable expansion of variable strings
        Opt('ExpandVarStrings', True)
        ; $varName = '$varName (expanded to get value)
        $varName = $varName
        ; disable expansion of variable strings
        Opt('ExpandVarStrings', False)
        ConsoleWrite('Variable: ' & $parName & ' = Value: ' & $varName & @LF)
    EndIf
EndFunc

Output:

Variable: $strName = Value: Harry
Variable: $strName = Value: Harry

:mellow:

But that is just a complicated way of doing this

ConsoleWrite('$strName = ' & $strName & @CRLF)

AutoIt must store the variable name internally or Eval wouldn't work but I don't know how to get to it.

Maybe a messy way would work.

Global Enum $apples = 0, $oranges, $bananas, $pineapples
Global $names[4] = ['$apples','$oranges','$bananas','$pineapples']
Global $v[4]

$v[$apples] = 2
$v[$oranges] = 3
$v[$bananas] = 'yellow'
$v[3] = 'fruit'

Printout($pineapples)

PrintOut(2)

Func PrintOut($sP)

    ConsoleWrite($names[$sP] & ' = ' & $v[$sP] & @CRLF)
EndFunc ;==>PrintOut
Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

AutoIt must store the variable name internally or Eval wouldn't work but I don't know how to get to it.

martin,

When you figure it out, let me know. :party:

Maybe a messy way would work.

Oh yeah, and as if that is not complicated either. :P:mellow:

Share this post


Link to post
Share on other sites

martin,

When you figure it out, let me know. :party:

Oh yeah, and as if that is not complicated either. :P:mellow:

I suppose you didn't understand my post.

The point is not that mine is simple; I was trying to produce a method which didn't rely on knowing which variable had to be printed when the script was written. With your method you hard code the variable name so then you might as well hard code printing out the name and no special function is needed.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Maybe one way would be to always have a 2 element array as your variable, [0] containint the variable name and [1] containing its value.

Local $Var1[2] = ["$Var1", "YourValue"]

_PrintOut($Var1)

Func _PrintOut($param)
    ConsoleWrite($param[0] & " = " & $param[1] & @CRLF)
EndFunc
Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

the only way of doing this afaik is to store the source somewhere and use @ScriptLineNumber in the Func

$source_location = @ScriptFullPath
$test = "testing"
$mytest = "123"
Debug($test)

MsgBox(0 ,"" , Debug($mytest))
Func Debug($var,$line=@ScriptLineNumber)
    $read = FileReadLine($source_location , $line)
    $array = StringRegExp($read,"Debug\((.*?)\)",3)
    If Not IsArray($array) Then Return 0
    ConsoleWrite($array[0] & " is '" & $var & "' on line " & $line & @CRLF)
    Return 1
EndFunc

Output:

$test is 'testing' on line 4
$mytest is '123' on line 6
Edited by Xand3r

Only two things are infinite, the universe and human stupidity, and i'm not sure about the former -Alber EinsteinPractice makes perfect! but nobody's perfect so why practice at all?http://forum.ambrozie.ro

Share this post


Link to post
Share on other sites

I suppose you didn't understand my post.

The point is not that mine is simple; I was trying to produce a method which didn't rely on knowing which variable had to be printed when the script was written. With your method you hard code the variable name so then you might as well hard code printing out the name and no special function is needed.

Oh, you consider my UDFs as hard coded you state. Lets put it to a test with your UDF and my UDFs at evaluating a variable passed to it and see the results.

$strName = "Harry"

_PrintOutStrVar('$strName$')
_PrintOutEnvVar('$strName$')

; lets do a lemon to check for hard coding myth
$lemon = $strName
_PrintOutStrVar('$lemon$')
_PrintOutStrVar('$lemon$')

Exit

Func _PrintOutStrVar($varName)
    Local $parName
    ; if value of $varName has $ on both ends of string
    If StringLeft($varName, 1) = '$' And StringRight($varName, 1) = '$' Then
        ; remove last $ char in parameter string
        $parName = StringTrimRight($varName, 1)
        ; remove 1st $ char in parameter string and evaluate to get value
        $varName = Eval(StringTrimLeft($parName, 1))
        ConsoleWrite('Variable: ' & $parName & ' = Value: ' & $varName & @LF)
    EndIf
EndFunc

Func _PrintOutEnvVar($varName)
    Local $parName
    ; if value of $varName has $ on both ends of string
    If StringLeft($varName, 1) = '$' And StringRight($varName, 1) = '$' Then
        ; remove last $ char in parameter string
        $parName = StringTrimRight($varName, 1)
        ; enable expansion of variable strings
        Opt('ExpandVarStrings', True)
        ; $varName = '$varName$' (expanded to get value)
        $varName = $varName
        ; disable expansion of variable strings
        Opt('ExpandVarStrings', False)
        ConsoleWrite('Variable: ' & $parName & ' = Value: ' & $varName & @LF)
    EndIf
EndFunc

Output:

Variable: $strName = Value: Harry
Variable: $strName = Value: Harry
Variable: $lemon = Value: Harry
Variable: $lemon = Value: Harry

It gave me what I expect from the variable passed to the UDFs.

Now your UDF.

Global Enum $apples = 0, $oranges, $bananas, $pineapples
Global $names[4] = ['$apples','$oranges','$bananas','$pineapples']
Global $v[4]

$v[$apples] = 2
$v[$oranges] = 3
$v[$bananas] = 'yellow'
$v[3] = 'fruit'

Printout($pineapples)

PrintOut(2)

; lets do a lemon to check for hard coding myth
$lemon = $pineapples
PrintOut($lemon)

Func PrintOut($sP)

    ConsoleWrite($names[$sP] & ' = ' & $v[$sP] & @CRLF)
EndFunc ;==>PrintOut

Output:

$pineapples = fruit
$bananas = yellow
$pineapples = fruit

The last line should be "$lemon = fruit" so it failed. And you want to accuse me of some mythical hard coding that you conjured up. I pity your standard of evaluation which lead to your flawed accusation. Recoding something into an array does not make it any better when you just want to handle variables to start with and get their name as the OP wants. Again, I pity you.

Share this post


Link to post
Share on other sites

Is there anything wrong with this one?

$Something = 'test value'
VarWrite('$Something')
Func VarWrite($Var)
    ConsoleWrite($Var & ' = ' & Execute($Var) & @CRLF)
EndFunc

I think this way is simple. However, the parameter have to be quoted to adapt with your function. Instead of we would like the parameter is the variable name like VarWrite($Something) we have to quote it VarWrite('$Something')

Anyway, this is good but it will be better if we can build a function allow to use variable as parameter nartually: VarWrite($Something)

Share this post


Link to post
Share on other sites

Could please a developer of AutoIt respond to this? How does Eval handle the problem of finding the Variable? AutoIt HAS to store the names of the variants somewhere, right?

Please consider the following code. I have had this problem when reading Ini Files. I worked around it by just passing the variable name to the function. But this is not really satisfying.

global $iniFile = "test.ini"

main()


func main()
    local $helloWorld

    readConfigVar($helloWorld,"helloWorld")

    MsgBox(0,"debug",$helloWorld)
EndFunc


func readConfigVar(byref $variable,$varName)
    local $buffer

    $buffer = IniRead(@ScriptDir & "\" & $iniFile,"test",$varName,"default")
    if StringCompare($buffer,"default")=0 Then
        msgbox(0,"Warning","Could not read variable " & $varName & " " & @ScriptDir & "\" & $iniFile,300)
        Exit
    Else
        $variable = $buffer
    EndIf
EndFunc

Place the test ini file in the same folder as the script. Contents of test.ini:

[test]

helloWorld = "This is a test string"

Share this post


Link to post
Share on other sites

Even if autoit keeps a list of declared vaiables somewhere I doubt you could write a function to access it, simply because the function does not get the variable passed, but instead the data inside the variable. (this is an assumption. I know nothing about the internal workings of autoit)

If you had a list of vaiables to itterate through, you could search for a variable with matching contents and display it's name, but there would be no way to tell two variables with identical content appart.

Share this post


Link to post
Share on other sites

AutoIt does (did) keep track of variable internally of course, but the functions to work with it are not public facing:

AUT_RESULT AutoIt_Script::F_Eval(VectorVariant &vParams, Variant &vResult)
{
    bool    bConst = false;

    if (g_oVarTable.isDeclared(vParams[0].szValue()))
    {
        Variant *pvTemp;
        g_oVarTable.GetRef(vParams[0].szValue(), &pvTemp, bConst);
        vResult = *pvTemp;
        return AUT_OK;
    }
        ...
}

the function calls an internal GetRef method:

bool VariableTable::GetRef(AString sVarName, Variant **pvVariant, bool &bConst, int nReqScope)
{
    Variant *lpVar = NULL;

    sVarName.toupper();                         // Always use uppercase to force case insensitive operation

    switch (nReqScope)
    {
        case VARTABLE_ANY:
            if (!m_Locals.empty())
                lpVar = m_Locals.top()->findvar(sVarName.c_str(), bConst);

            if (lpVar == NULL)
                lpVar = m_Globals.findvar(sVarName.c_str(), bConst);

            break;

        case VARTABLE_FORCELOCAL:
            if (!m_Locals.empty())
                lpVar = m_Locals.top()->findvar(sVarName.c_str(), bConst);
            else
                lpVar = m_Globals.findvar(sVarName.c_str(), bConst);

            break;

        case VARTABLE_FORCEGLOBAL:
            lpVar = m_Globals.findvar(sVarName.c_str(), bConst);
            break;
    }

    *pvVariant = lpVar;

    return (lpVar != NULL);

} // GetRef()

Which calls the findvar method on the appropriate variable scope:

Variant* VariableList::findvar(const char *szName, bool &bConst)
{
    VarNode *lpTemp = findvarnode(szName);

    if (lpTemp)
    {
        bConst = lpTemp->bConst;
        return lpTemp->pvVariant;           // Found!  Return a pointer to it
    }
    else
        return NULL;

} // findvar()

Which in turn uses findvarnode to get the NODE pointer:

VarNode* VariableList::findvarnode(const char *szName)
{
    VarNode *lpTemp = m_lpRoot;
    int nRes;

    while (lpTemp != NULL)
    {
        nRes = strcmp(lpTemp->szName, szName);

        if (nRes < 0)
            lpTemp = lpTemp->lpLeft;            // Less than (left child)
        else if (nRes > 0)
            lpTemp = lpTemp->lpRight;           // Greater than (right child)
        else
            return lpTemp;                      // Found
    }

    // Not found
    return NULL;

} // findvarnode()

This is off the last public version of the source code. The underlaying issue is simply that there doesn't seem to be a public facing function for findvar. In "userland", the global vs public scope get messed up when you try to pass a global variable to a local function (the variable is copied by value or at least via reference, so the global variable name is not preserved in the local scope...), so I don't think it's possible to pass just a variable, it would have to be the name as a string like the examples aboves.

Share this post


Link to post
Share on other sites

Something like this is possible?

Dim $a[4] = [1,2,3,4]
ArrayWrite("$a")
Func ArrayWrite($Var)
ConsoleWrite($Var & " = " & _ArrayToString((Execute($Var),",")) & @CRLF);does not work...
;ConsoleWrite($Var & " = " & _ArrayToString($a,",") & @CRLF)
EndFunc

m(o.O)m

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