Globale Variablen in einer Funktion definieren - möglich?

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

GEV
Posts: 1002
Joined: 25 Feb 2014, 00:50

Globale Variablen in einer Funktion definieren - möglich?

17 Jun 2018, 02:15

Einfaches Beispiel:

Dies funktioniert:

Code: Select all

; D:\Scripts\lib\move_A_to_Pos1.ahk
move_A_to_Pos1(){
	WinMove, A,, X1
}

; D:\Scripts\lib\move_A_to_Pos2.ahk
move_A_to_Pos2(){
	WinMove, A,, X2
}

; D:\Scripts\Script1.ahk
#NoEnv
#SingleInstance Force

global X1 := Round(0.041*A_ScreenWidth)
global X2 := Round(0.09*A_ScreenWidth)

$F1::move_A_to_Pos1()
$F2::move_A_to_Pos2()
dies aber nicht:

Code: Select all

; D:\Scripts\lib\move_A_to_Pos1.ahk
move_A_to_Pos1(){
	WinMove, A,, X1
}

; D:\Scripts\lib\move_A_to_Pos2.ahk
move_A_to_Pos2(){
	WinMove, A,, X2
}

; D:\Scripts\lib\Global_Variables.ahk
Global_Variables(){
global X1 := Round(0.041*A_ScreenWidth)
global X2 := Round(0.09*A_ScreenWidth)
}

; D:\Scripts\Script2.ahk
#NoEnv
#SingleInstance Force

$F3::move_A_to_Pos1()
$F4::move_A_to_Pos2()
Ich will nämlich diese Variablen in mehreren Skripten (in D:\Scripts) benutzen, ohne sie in jedem einzelnen explicit definieren zu müssen oder #include benutzen.
Ist sowas möglich?
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Globale Variablen in einer Funktion definieren - möglich?

17 Jun 2018, 02:51

Moin,

super-globale Variablen können in Funktionen nicht definiert werden, weil das Schlüsselwort Global innerhalb und außerhalb von Funktionen unterschiedliche Auswirkungen hat.

Innerhalb von Funktionen bedeutet es, dass auf eine globale Variable zugegriffen werden soll. Außerhalb von Funktionen wird eine super-globale Variable angelegt.

Die Funktion Global_Variables() im zweiten Beispiel muss aufgerufen werden, damit die Variablen X1 und X2 mit Werten versorgt werden. Sonst werden beim Start des SKripts nur leere Variablen angelegt.

Ähnlich ist es bei den super-globalen Variablen. Wenn eine Zeile wie global X1 := Round(0.041*A_ScreenWidth) nicht ausgeführt wird, entsteht nur eine leere super-globale Variable.

Es sollte klappen, wenn Du das Lib-Skript "D:\Scripts\lib\Global_Variables.ahk" änderst. Das sieht zwar nicht unbedingt elegant aus, sollte aber funktionieren:

Code: Select all

Global X1, X2 ; legt beim Start des Skripts die super-globalen Variablen X1 und X2 an
Global_Variables(){
   Static VarInit := Global_Variables() ; die Funktion ruft sich beim Start des Skripts einmal selbst auf und füllt die Variablen
   X1 := Round(0.041*A_ScreenWidth)
   X2 := Round(0.09*A_ScreenWidth)
}
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Globale Variablen in einer Funktion definieren - möglich?

17 Jun 2018, 02:56

Nein ist es nicht - es ist absolut verboten und wäre auch gegen die Idee von Funktionen.
Du musst wissen dass es mehrere Scopes gibt.
Die variable X1 und X2 sind in deinem ersten Skript super-global.
Die Variablen in deinem 2. Skript sind aber nur global:

Code: Select all

globalVar := 1			;global
global superGlobalVar := 2 	;super-global

funktion1() {
	global globalVar ;um eine globale variable in dein Skript zu holen.
	static staticVar := 3 	;static
	localVar := 4		;local
	Msgbox %globalVar%`n%superGlobalVar%`n%staticVar%`n%localVar%
}

funktion1() {
	;wenn du global von globalVar weg lässt wird sie nicht eingebunden.
	static staticVar := 3 	;static
	localVar := 4		;local
	Msgbox %globalVar%`n%superGlobalVar%`n%staticVar%`n%localVar%
}
An sich würde es sich für dich mehr sinn machen mit globalen anstatt super-globalen zu arbeiten, wenn du die Variablendefinitionen unbedingt in Funktionen packen willst.
Was an sich absolut nicht geht ist die variablen zu bekommen ohne sie explizit zu definieren oder per #include woanders her zu bekommen.
Du kannst nichts bekommen wenn du es nicht erschaffst oder woanders her bekommst das macht keinen Sinn.

Wenn du erläutern würdest wieso du das überhaupt machen willst dann wäre diese Fragestellung leichter zu verstehen.
Recommends AHK Studio
GEV
Posts: 1002
Joined: 25 Feb 2014, 00:50

Re: Globale Variablen in einer Funktion definieren - möglich?

17 Jun 2018, 12:29

@just me, @nnnik,
erstmal vielen Dank für eure Erläuterungen und Funktionen.
Ich muss gestehen, dass ich mich mit diesem Thema noch nicht ausgiebig genug befasst habe, um eure Erläuterungen gänzlich zu verstehen und will es nachholen.
Nach blindem Experimentieren mit just me's Funktion hab ich rausgefunden, dass sie nur funktioniert, wenn ich sie im Skript (noch) einmal aufrufe (egal an welcher Stelle):

Code: Select all

; D:\Scripts\lib\move_A_to_Pos1.ahk
move_A_to_Pos1(){
	WinMove, A,, X1
}

; D:\Scripts\lib\move_A_to_Pos2.ahk
move_A_to_Pos2(){
	WinMove, A,, X2
}

; D:\Scripts\lib\Global_Variables.ahk
Global X1, X2 ; legt beim Start des Skripts die super-globalen Variablen X1 und X2 an
Global_Variables(){
   Static VarInit := Global_Variables() ; die Funktion ruft sich beim Start des Skripts einmal selbst auf und füllt die Variablen
   X1 := Round(0.041*A_ScreenWidth)
   X2 := Round(0.09*A_ScreenWidth)
}

; D:\Scripts\Script2.ahk
#NoEnv
#SingleInstance Force

Global_Variables()  ; muss im Skript (noch) einmal aufgerufen werden (egal an welcher Stelle)

$F1::move_A_to_Pos1()
$F2::move_A_to_Pos2()
Vielleicht kann jemand erklären, wieso.
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Globale Variablen in einer Funktion definieren - möglich?

17 Jun 2018, 12:40

Muss nicht nochmal aufgerufen werden, muss nur im script vorkommen. zB mittels #Include
GEV
Posts: 1002
Joined: 25 Feb 2014, 00:50

Re: Globale Variablen in einer Funktion definieren - möglich?

17 Jun 2018, 13:18

@wolf_II,
Ist

Code: Select all

#Include <Global_Variables> ; wird einmal beim Start eingebunden
nicht ein und dasselbe wie

Code: Select all

Global_Variables() ; wird einmal beim Start aufgerufen
?
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Globale Variablen in einer Funktion definieren - möglich?

17 Jun 2018, 13:31

Meiner Meinung nach nicht.
Der Unterschied ist: wenn du aufrufst, dann brauchst du den static Krempel nicht.
Wenn Du einbindest, dann ist der static Krempel hilfreich (zwingend erforderlich) um die globals zu generieren befüllen.

Man kann auch argumentieren der Effekt sei gleich, und da stimme ich zu.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Globale Variablen in einer Funktion definieren - möglich?

17 Jun 2018, 13:53

AHK bindet beim Start automatisch gewisse Skripte ein, wenn gewisse Bedingungen erfüllt sind.
Dein Skript muss einen Funktionsaufruf haben für den keine Funktion definiert ist.
Die Datei die die Funktion enthält muss sich in einem der automatisch erkannten #include Ordnern befinden.

Wenn du keinen Funktionsaufruf und kein Include hast wird AutoHotkey gar nicht erst versuchen nach deinem Skript zu suchen.
Du kannst nicht dafür sorgen, dass AutoHotkey Code einbindet ohne jegliche Referenz.
Recommends AHK Studio
GEV
Posts: 1002
Joined: 25 Feb 2014, 00:50

Re: Globale Variablen in einer Funktion definieren - möglich?

17 Jun 2018, 14:49

Ich glaube, ich fange an, eure Logik zu verstehen.
Es muss eine direkte Verbindung zwischen Skript und Funktion hergestellt werden (per #include oder Funktionsauruf).
Die Global_Variables()-Funktion wird nicht nochmal, sondern nur einmal beim Start aufgerufen und bleibt im Skript-Gedächtnis bis das Skript beendet wird.
Korrigiert mich, wenn ich es falsch verstehe.
GEV
Posts: 1002
Joined: 25 Feb 2014, 00:50

Re: Globale Variablen in einer Funktion definieren - möglich?

18 Jun 2018, 10:12

Die Lösung zu meiner Frage sieht dann folgendermassen aus (falls jemand was Ähnlices verwenden will):

D:\Scripts\lib\move_A_to_Pos1.ahk

Code: Select all

move_A_to_Pos1(){
	Global_Variables()
	WinMove, A,, X1
}
D:\Scripts\lib\move_A_to_Pos2.ahk

Code: Select all

move_A_to_Pos2(){
	Global_Variables()
	WinMove, A,, X2
}
D:\Scripts\lib\Global_Variables.ahk
https://autohotkey.com/boards/viewtopic ... 74#p224374

Code: Select all

Global X1, X2 ; legt beim Start des Skripts die super-globalen Variablen X1 und X2 an
Global_Variables(){
   ; Static VarInit := Global_Variables() ; die Funktion ruft sich beim Start des Skripts einmal selbst auf und füllt die Variablen
   X1 := Round(0.041*A_ScreenWidth)
   X2 := Round(0.09*A_ScreenWidth)
}
D:\Scripts\Script1.ahk

Code: Select all

#NoEnv
#SingleInstance Force

$F1::move_A_to_Pos1()
$F2::move_A_to_Pos2()
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Globale Variablen in einer Funktion definieren - möglich?

18 Jun 2018, 10:50

Deine Lösung funktioniert. Nun stell Dir mal vor, Du selbst willst später mal so was in der Art benutzen.
In 2 Wochen wirst Du möglicherweise denken: wie ging das noch? Wenn nicht dann in 2 Monaten oder länger.
Dann guckst Du erst in lib folder nach move_A_to_Pos1().ahk, dann siehst du die Global_Variables(), und so weiter.
Wenn Du heute ins Script1.ahk reinschreibst: #Include Global_Variables() dann ist das selbst-documentierender code. Vielfach besser als comments.

Weiter: warum musst Du bei jedem Aufruf von move_A_to_Pos1() oder move_A_to_Pos2() die globals neu berechnen? Einmal reicht, die ändern sich nicht während der Laufzeit die Scripts.

Ich denke die Lösung mit #Include und static Variablen hat viele Vorteile, besonders wenn du complexere Aufgaben angehst.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Globale Variablen in einer Funktion definieren - möglich?

18 Jun 2018, 11:04

Wobei eine Klasse als Kombination von Daten und Funktionalität GEVs Denkansatz vielleicht sehr zu gute kommen würde.
Recommends AHK Studio
GEV
Posts: 1002
Joined: 25 Feb 2014, 00:50

Re: Globale Variablen in einer Funktion definieren - möglich?

18 Jun 2018, 13:39

@wolf_II,
verzeih mein Halbwissen in diesem Bereich. Ich ging von der falschen Annahme aus, dass man im Library-Verzeichnis nur Funktionen definieren kann.
Danke für deine Hinweise, ich sehe jetzt ein, dass dies der bessere und direkteste Weg ist, damit mehrere Skripte die selben Variablenwerte in den Funktionen teilen können:

D:\Scripts\lib\move_A_to_Pos1.ahk

Code: Select all

move_A_to_Pos1(){
	WinMove, A,, X1
}
D:\Scripts\lib\move_A_to_Pos2.ahk

Code: Select all

move_A_to_Pos2(){
	WinMove, A,, X2
}
D:\Scripts\lib\Global_Variables.ahk

Code: Select all

Global X1 := Round(0.041*A_ScreenWidth)
Global X2 := Round(0.09*A_ScreenWidth)
D:\Scripts\Script1.ahk

Code: Select all

#NoEnv
#SingleInstance Force

#Include <Global_Variables>

$F1::move_A_to_Pos1()
$F2::move_A_to_Pos2()
@nnnik,
was du mit "Klasse als Kombination von Daten und Funktionalität" meinst, versteh ich nicht. Vielleicht könntest du erklären, was das ist.

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 34 guests