AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[solved] Creating a global variable via a function, sort of

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
hugov



Joined: 27 May 2007
Posts: 2181

PostPosted: Mon Nov 23, 2009 4:59 pm    Post subject: [solved] Creating a global variable via a function, sort of Reply with quote

Not sure how to explain this properly as I'm not that well
versed with byref global static etc Sad

I'm working on my new TF lib (see sig) and with the help
of Tuncay/Majkinetor I introduced a function to read a
text file and return a (named) global parameter.

TF("TextFile.txt") in it self works, so far so good.
It creates a global variabl T. T contains the text
from "TextFile.txt" and would be equivalent to
FileRead, T, TextFile.txt

TF("TextFile.txt",MyVar) also works, it creates a global
variable called MyVar but also creates the global var T,
so it would be equivalent to
FileRead, T, TextFile.txt
FileRead, MyVar, TextFile.txt

Initially I thought when I used the MyVar option it wouldn't
create the global T but over the last few days I found out it
does.

Of course it COULD have an undesired side effect if someone
uses T as a variable in their script and it replaces or creates T
without someone knowing. Personally I don't mind, but I wonder
if there is a solution

So I would like to use TF("TextFile.txt",MyVar) without it
creating a global var T - but it should create T if I simply
use TF("TextFile.txt"). I'm sure it makes no sense, but still
someone might understand what I mean Smile

The script below is what I have and illustrates the behaviour described above, perhaps it makes it easier to understand. I fiddled with byref
etc but to no avail.

Code:
;__TF(A_ScriptName) ; Will create global var T as it should. A_ScriptName used here so we don't need to create a text file for testing
__TF(A_ScriptName,MyVar) ; Will create global var MyVar as it should, but also T. A_ScriptName used here so we don't need to create a text file for testing

MsgBox % "T-------:" T
MsgBox % "MyVar---:" MyVar

__TF(TextFile, byref t = "") { ; read contents of file in t and return it, create t if omitted in TF call
    FileRead, t, %TextFile%
    if (t != "")
      {
         __TF_setGlobal("t", t)
         return (__TF_getGlobal("t"))
      }
   }

__TF_GetGlobal(var) ; Credits Tuncay & Majkinetor http://www.autohotkey.com/forum/viewtopic.php?p=297301#297301
   {
     global
     var := %var%
     return var
   }

__TF_SetGlobal(var, content = "") ; Credits Tuncay & Majkinetor http://www.autohotkey.com/forum/viewtopic.php?p=297301#297301
   {
     global
     %var% := content
   }

_________________
Tut 4 Newbies
TF : Text file & string lib, TF Forum


Last edited by hugov on Tue Nov 24, 2009 9:56 am; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
Peter



Joined: 30 Dec 2005
Posts: 448

PostPosted: Mon Nov 23, 2009 6:34 pm    Post subject: Reply with quote

So what you are saying is, when there is a 2nd parameter used, there shouldn't be made a global variable. That's happening here (unless you make b=0):
Code:
   Fct(5)
   msgbox,,1: global address, % &x . "  x= " . x      ; x is empty, cuz nowhere initialized
   b := 100
   c := Fct(5, b)
   msgbox,,2: global address, % &x . "  x= " . x      ; x = 10 via TF_SetGlobal
   ; But this x variable is NOT the same variable as local variable x in Fct().
   ; Compare the addresses and you will see. It only has the same name and the same value.
   ; That's the whole purpose of local variables, to distinguish them from globals.
   ; In other words, TF_SetGlobal can create a global variable with the same name and content,
   ; but it doesn't set a local variable to global
   msgbox c= %c%
return

Fct(var, byref y= 0){
   x := var * 2
   msgbox,,local address, % &x
   if (y <> 0){      ; 2nd parameter used will create the global variable x
      __TF_setGlobal("x", x)
      return (__TF_getGlobal("x"))
   }
}
__TF_GetGlobal(var){ ; Credits Tuncay & Majkinetor http://www.autohotkey.com/forum/viewtopic.php?p=297301#297301
  global
  var := %var%
  return var
}
__TF_SetGlobal(var, content = ""){ ; Credits Tuncay & Majkinetor http://www.autohotkey.com/forum/viewtopic.php?p=297301#297301
  global
  %var% := content
   msgbox,,global in SetGlobal, % &x
}
I don't know what your purpose is, but I always try to avoid global variables. It's easier to use them, but it's prone to conflicts when you start including other scripts.
Back to top
View user's profile Send private message
hugov



Joined: 27 May 2007
Posts: 2181

PostPosted: Mon Nov 23, 2009 6:45 pm    Post subject: Reply with quote

Thanks for your reply.
Peter wrote:
So what you are saying is, when there is a 2nd parameter used, there shouldn't be made a global variable. That's happening here (unless you make b=0)... I don't know what your purpose is, but I always try to avoid global variables. It's easier to use them, but it's prone to conflicts when you start including other scripts.
No, that is not what I'm saying (told you it was confusing) Wink The entire purpose is to create a global var for further processing, and I know about local/global. That isn't the problem.

TF("TextFile.txt") ; Works OK, creates T that is what I want, So far so good!

TF("TextFile.txt", MyVar) ; Works ALMOST OK, creates MyVar that is what I want, but it ALSO create a global var T (by definition it ALWAYS creates global var T)

MyVar is the name of the global var it SHOULD create, it does so that part works.

I don't want to have a global var T IF I create MyVar. Instead of one it generates two: MyVar and T, I just want MyVar

I don't know how to explain it, just try what I posted to see what I mean.

So again, TF("TextFile.txt", MyVar) should only create MYVAR not T as well.
_________________
Tut 4 Newbies
TF : Text file & string lib, TF Forum
Back to top
View user's profile Send private message Visit poster's website
jaco0646



Joined: 07 Oct 2006
Posts: 1770
Location: MN, USA

PostPosted: Mon Nov 23, 2009 10:28 pm    Post subject: Reply with quote

Code:
;__TF(A_ScriptName)        ;return only T
__TF(A_ScriptName,"MyVar") ;return only MyVar

MsgBox % "T-------:" T
MsgBox % "MyVar---:" MyVar

__TF(TextFile, output = "T") {
    global
    FileRead, %output%, %TextFile%
    Return, (%output%)
   }

_________________
http://autohotkey.net/~jaco0646/
Back to top
View user's profile Send private message Visit poster's website
Peter



Joined: 30 Dec 2005
Posts: 448

PostPosted: Tue Nov 24, 2009 4:59 am    Post subject: Reply with quote

HugoV wrote:
I don't know how to explain it, just try what I posted to see what I mean.
Done that yesterday, but it seems it didn't help me then Wink.
Before I go much further with this hocus-pocus code, I have another question:
Quote:
__TF(A_ScriptName,MyVar) ; caller
__TF(TextFile, byref T = "") ; definition

So depending on how the function is called, it must create an extra global variable?
1. without 2nd parameter: create global variable T [can be detected by checking default value of 2nd parameter T]
2. with 2nd parameter: create only global variable MyVar (same name as the parameter in the caller)
NB: MyVar will ALWAYS be global (or known outside the function) because of ByRef, albeit empty or not.
If so, then it's like this:
Code:
; __TF(A_ScriptName) ; Will create global var T as it should. A_ScriptName used here so we don't need to create a text file for testing
; Either check on a special string in __TF, or initiliaze MyVar here, so it can be detected in __TF()
 __TF(A_ScriptName,MyVar) ; Will create global var MyVar as it should, and no T.

MsgBox,,T, % "T-------:" T
MsgBox,,MyVar, % "MyVar---:" MyVar

__TF(TextFile, byref t = "aStringThatCallerNeverContains") { ; read contents of file in t and return it, create t if omitted in TF call
    createGlobal := (t = "aStringThatCallerNeverContains") ? true : false      ; check on presence of 2nd parameter
    FileRead, t, %TextFile%
    if (createGlobal)
      {
         __TF_setGlobal("t", t)
         return (__TF_getGlobal("t"))
      }
   }

__TF_GetGlobal(var) ; Credits Tuncay & Majkinetor http://www.autohotkey.com/forum/viewtopic.php?p=297301#297301
   {
     global
     var := %var%
     return var
   }

__TF_SetGlobal(var, content = "") ; Credits Tuncay & Majkinetor http://www.autohotkey.com/forum/viewtopic.php?p=297301#297301
   {
     global
     %var% := content
   }
Back to top
View user's profile Send private message
tank



Joined: 21 Dec 2007
Posts: 2294
Location: Louisville KY USA

PostPosted: Tue Nov 24, 2009 5:20 am    Post subject: Reply with quote

Based on what i see jaco0646 has the right answer
_________________
Basic Webpage Controls with JavaScript / COM - Tutorial by Jethrow
Back to top
View user's profile Send private message
Peter



Joined: 30 Dec 2005
Posts: 448

PostPosted: Tue Nov 24, 2009 6:33 am    Post subject: Reply with quote

tank wrote:
Based on what i see jaco0646 has the right answer
Indeed, when I look further into it it seems quite good.
But if I play a bit with it, this code gives the same result.
Code:
 __TF(A_ScriptName)        ;return only T
; __TF(A_ScriptName,"MyVar") ;return only MyVar

MsgBox % "T-------:" T
MsgBox % "MyVar---:" MyVar

__TF(TextFile, output = "T") {
    ; global   ; is not necessary?!
    FileRead, %output%, %TextFile%
    Return        ;  (%output%)
   }
And that raises the question, why do I get the value content, if I nowhere declare something global? The answer lies probably here (from AHKHelp):
Quote:
Within a function, any dynamic variable reference such as Array%i% always resolves to a local variable unless no variable of that name exists, in which case a global is used if it exists.
Back to top
View user's profile Send private message
hugov



Joined: 27 May 2007
Posts: 2181

PostPosted: Tue Nov 24, 2009 9:55 am    Post subject: Reply with quote

Thanks guys. Before I turned on my PC today I thought it must be very easy to solve, and guess what, it was Cool
_________________
Tut 4 Newbies
TF : Text file & string lib, TF Forum
Back to top
View user's profile Send private message Visit poster's website
jaco0646



Joined: 07 Oct 2006
Posts: 1770
Location: MN, USA

PostPosted: Tue Nov 24, 2009 5:55 pm    Post subject: Reply with quote

Peter wrote:
why do I get the value content, if I nowhere declare something global?

AHK Help File wrote:
Common source of confusion: Any non-dynamic reference to a variable creates that variable the moment the script launches. For example, when used outside a function, MsgBox %T% creates T as a global the moment the script launches.

Without using global inside the function, you will not be able to dynamically reference T outside the function.
_________________
http://autohotkey.net/~jaco0646/
Back to top
View user's profile Send private message Visit poster's website
hugov



Joined: 27 May 2007
Posts: 2181

PostPosted: Tue Nov 24, 2009 6:04 pm    Post subject: Reply with quote

Although the issue it seems solved, I do have a question.

While testing I noticed that jaco0646 solutions works when I use
Code:
XF(TextFile, output = "T") {
    global
    FileRead, %output%, %TextFile%
    Return, (%output%)
   }
But when I remove the () e.g. a simple return, %output% it doesn't work when I nest a function call.

What does the () do in this particular case, don't see any explanation at http://www.autohotkey.com/docs/commands/Return.htm but haven't search documentation any further

Edit: the answer is on the page I linked to
Embarassed Embarassed Embarassed Embarassed
_________________
Tut 4 Newbies
TF : Text file & string lib, TF Forum


Last edited by hugov on Wed Nov 25, 2009 8:08 pm; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
jaco0646



Joined: 07 Oct 2006
Posts: 1770
Location: MN, USA

PostPosted: Tue Nov 24, 2009 7:13 pm    Post subject: Reply with quote

The explanation is on the Return page you linked to.
AHK Help File wrote:
Known limitation: For backward compatibility and ease-of-use, the following two examples are functionally identical:

return MyVar
return %MyVar%

In other words, a single variable enclosed in percent signs is treated as a non-expression. To work around this, make it unambiguously an expression by enclosing it in parentheses; for example: return (%MyVar%)

_________________
http://autohotkey.net/~jaco0646/
Back to top
View user's profile Send private message Visit poster's website
hugov



Joined: 27 May 2007
Posts: 2181

PostPosted: Tue Nov 24, 2009 7:17 pm    Post subject: Reply with quote

Embarassed Embarassed Embarassed Embarassed
I'm so blind, thanks for showing me the errors of my ways.

How much fun it is to feel like a noob again (or still) Cool Wink
_________________
Tut 4 Newbies
TF : Text file & string lib, TF Forum
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group