Access a variable from one function inside another function

Get help with using AutoHotkey and its commands and hotkeys
john_c
Posts: 175
Joined: 05 May 2017, 13:19

Access a variable from one function inside another function

20 Feb 2018, 13:24

Here are 2 functions, the 1st is called inside 2nd. What will be the proper way to invoke "foo" variable inside function2()?

For example, this works, but I understand that this is bad practise:

Code: Select all

function1() {
	foo := "Hello, John!"
}

function2() {
	function1()
	if foo = Hello, John!
		msgBox, Hello Mike!
}

global foo
function2()
User avatar
boiler
Posts: 2372
Joined: 21 Dec 2014, 02:44

Re: Access a variable from one function inside another function

20 Feb 2018, 13:52

Just return the value of the function.

Code: Select all

function1() {
	return "Hello, John!"
}

function2() {
	foo := function1()
	if foo = Hello, John!
		msgBox, Hello Mike!
}
The main takeaway is that you should get away from thinking that functions share variables and/or variable names. Even if you used a variable inside function1, it could be named foo, but it could be named something else, and it wouldn't matter because it would be unrelated to the other foo other than what you do with it when you get the returned value.
john_c
Posts: 175
Joined: 05 May 2017, 13:19

Re: Access a variable from one function inside another function

20 Feb 2018, 14:05

boiler wrote:...
Thanks again! Your answers are always amazing! :-)
john_c
Posts: 175
Joined: 05 May 2017, 13:19

Re: Access a variable from one function inside another function

20 Feb 2018, 14:27

@boiler

So, as I understand from what you said, this will be impossible?

Code: Select all

function1() {
	person1 := "John"
	person2 := "Jill"
}

function2() {
	msgBox, %person1%
	msgBox, %person2%
}

function2()
User avatar
nnnik
Posts: 3564
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Access a variable from one function inside another function

20 Feb 2018, 14:46

john_c thats when you return an array.

Code: Select all

function1() {
	person := []
	person.1 := "John"
	person.2 := "Jill"
	return person
}

function2() {
	person := function1()
	msgBox, % person.1
	msgBox, % person.2
}

function2()
Another method would be to use global variables and the global scope:

Code: Select all

function1() {
	global person
	person := []
	person.1 := "John"
	person.2 := "Jill"
}

function2() {
	global person
	msgBox, % person.1
	msgBox, % person.2
}

function1()
function2()
This might seem easier at first however it gets difficult once you have like 30 functions and need to control 300 variables.
You might end up naming 2 variables the same way.

Arguably the best method is to use classes - however that's a little bit advanced so I won't explain it here.
Recommends AHK Studio
Odlanir
Posts: 274
Joined: 20 Oct 2016, 08:20

Re: Access a variable from one function inside another function

20 Feb 2018, 14:54

Or even:

Code: Select all

global person1,person2

function1() {
	person1 := "John"
	person2 := "Jill"
}

function2() {
	function1()
	msgBox, %person1%
	msgBox, %person2%
}

function2()
____________________________________________________________________________
Windows 7 Home Premium 64 bit - Autohotkey v1.1.24.02 64-bit Unicode
User avatar
boiler
Posts: 2372
Joined: 21 Dec 2014, 02:44

Re: Access a variable from one function inside another function

20 Feb 2018, 16:03

Another alternative is using ByRef, which allows you to return values directly into the variables in your function call:

Code: Select all

function1(ByRef p1, ByRef p2) {
	p1 := "John"
	p2 := "Jill"
}

function2() {
	function1(person1, person2)
	msgBox, %person1%
	msgBox, %person2%
}

function2()
FanaticGuru
Posts: 1238
Joined: 30 Sep 2013, 22:25

Re: Access a variable from one function inside another function

20 Feb 2018, 17:36

On a tangent note, sometimes you might want to use a gosub which is similar to a function in flow of control in that you jump somewhere and then return but it does not limit anything to a local scope. Everything stays in the global scope which can sometimes be useful.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts

AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon

[Function] Timer - Create and Manage Timers
john_c
Posts: 175
Joined: 05 May 2017, 13:19

Re: Access a variable from one function inside another function

21 Feb 2018, 08:10

Boiler, Nnnik, Odlanir, FanaticGuru - thank you all! Well, it seems there are a lot of thing to learn for!
User avatar
evilC
Posts: 4373
Joined: 27 Feb 2014, 12:30

Re: Access a variable from one function inside another function

21 Feb 2018, 11:47

What you maybe want is a class.
With a class, you can store variables in the class, and the functions ("methods") of the class can also access these variables.

Code: Select all

#SingleInstance force
#Persistent

mc := new MyClass()
mc.function1()
mc.function2()

class MyClass {
	function1() {
		this.person1 := "John"
		this.person2 := "Jill"
	}

	function2() {
		msgBox, % this.person1
		msgBox, % this.person2
	}
}
However, rather than hard-coding the names, you would normally pass them in in the "constructor":

Code: Select all

mc := new MyClass("John", "Jill")
mc.function2()

class MyClass {
	__New(name1, name2) {
		this.person1 := name1
		this.person2 := name2
	}

	function2() {
		msgBox, % this.person1
		msgBox, % this.person2
	}
}
Classes are really useful if you want to group multiple bits of data together and use them in interesting ways.

Code: Select all

fred := new Person("Fred", 21)
bob := new Person("Bob", 16)

MsgBox % fred.BuildGreeting()
MsgBox % "Bob can order alcohol: " bob.CanOrderAlcohol()

class Person {
	__New(name, age){
		this.name := name
		this.age := age
	}
	
	BuildGreeting(){
		return % "Hi, my name is " this.name ", and I am " this.age " years old"
	}
	
	CanOrderAlcohol(){
		if (this.age >= 18){
			return true
		}
		return false
	}
}

Return to “Ask For Help”

Who is online

Users browsing this forum: Albireo, Bridgeman, Helgef, hunter_finn, jarvis, sinbad, vvhitevvizard and 40 guests