Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- [Tutorial] Globale und Lokale Variablen
- Guten Tag,
- da man immer wieder leicht sehen kann, dass manche Leute ohne konkrete Kompetenzen im Bereich der Variablen in LUA / MTA stets Fehler machen und korrekte Aussagen bestreiten,
- habe ich mir die Zeit genommen ein kleines Tutorial zum Thema globale und lokale Variablen zu schreiben.
- Einleitung
- (Für die Richtigkeit dieses Tutorials und dessen Angaben übernehme ich keine Haftung.)
- Es gibt in LUA viele Arten von Variablen. Dazu gehören globale Variablen und lokale Variablen.
- Wir ignorieren nun mal den Fakt das jede Variable ein gewissen Datentypen besitzt. In Lua wird der Datentyp intern (und ein wenig Extern) behandelt.
- Was genau eine Variable ist habt ihr alle in der Schule gelernt. Deshalb werden wir dieses Thema auch überspringen.
- Initialisierung & Deklaration
- Die oben genannten Wörter spielen in Lua nicht so eine grosse Rolle wie in anderen Programmiersprachen.
- Jedoch sollte man auch den Unterschied zwischen den beiden Wörtern kennen, weshalb ich diesen kurz Ansprechen werde.
- Deklaration
- Unter Deklaration versteht man das Bekanntmachen von Variablen.
- Variablen werden Deklariert und in etwa "Vorbereitet".
- In anderen Programmiersprachen koennte man das so schreiben:
- (Java:)
- [lua]
- int foo;
- [/lua]
- Die Bekanntmachung wird in Lua nur mit dem "local" Keyword sinnvoll.
- Initialisierung
- Bei der Initialisierung wird der Variable einen Wert zugewiesen. In Lua sieht das in etwa so aus:
- (Lua:)
- [lua]
- foo = 5;
- [/lua]
- Selbstverstaendlich kann man auch eine Variable deklarieren und gleichzeitig initalisieren.
- (Java:)
- [lua]
- int foo = 5;
- [/lua]
- Globale Variablen
- Eine globale Variable ist eine Variable, welche Ihr von jeder Stelle eures Scriptes aus verwenden und erreichen könnt.
- Beispiel von globalen Variablen:
- server/script.lua:
- [lua]
- bar = "bar";
- foo = bar;
- [/lua]
- Die Variablen "bar" und "foo" sind im kompletten Script erreichbar.
- Das veraendern dieser Variablen hat zufolge, dass diese Variable im kompletten Script geaendert wird.
- Lokale Variablen
- Eine Lokale Variable ist eine Variable, welche nur in einem gewissen Bereich (Block) existieren.
- Sie wird mit dem Prefix 'local' deklariert.
- Solltet Ihr eine Lokale Variable in der ersten Zeile eures Scriptes schreiben
- [lua]
- local x = 5;
- [/lua]
- So ist diese Variable nur in dieser Datei vorhanden.
- Der Gültigkeitsbereich dieser Variable limiert sich also nur auf diese Datei.
- Solltet Ihr eine Variable in einer Funktion deklarieren, so ist der Gültigkeitsbereich der Variable nur auf diese Funktion limitiert.
- [lua]
- function foo() -- Deklarierung und Initialisierung einer globalen Funktion
- local bar = 5; -- Deklarierung und Initialisierung einer lokalen Variable
- print(bar); -- Ausgabe: 5
- end
- print(bar); -- Ausgabe: nil;
- [/lua]
- Solltet Ihr diese Variable ohne den 'local' Prefix erstellt habe, so streckt sich der Gültigkeitsbereich der Variable automatisch auf das Gesammte Script aus.
- [lua]
- function foo() -- Deklarierung und Initialisierung einer globalen Funktion
- bar = 5; -- Deklarierung und Initialisierung einer Globalen Variable
- print(bar); -- Ausgabe: 5
- end
- print(bar); -- Ausgabe: 5;
- [/lua]
- Falls Ihr diese Variable trotzdem im gesammten Script verwenden möchtet, könnt Ihr diese Variable deklarieren und in einer Funktion initialisieren. So bleibt der Gültigkeitsbereich
- der Variable auf diese Datei beschränkt, kann jedoch modifiziert und zugänglich sein.
- [lua]
- local bar; -- Deklarierung der lokalen Variable
- function foo() -- Deklarierung und Initialisierung einer globalen Funktion
- bar = 5; -- Initialisierung der lokalen Variable
- local foo_bar = "bar"; -- Deklarierung und Initialisierung einer Lokalen Variable
- print(bar); -- Ausgabe: 5
- end
- -- Der Gültigkeitsbereich von "foo_bar" endet hier, da die Variable lokal beschränkt wurde
- print(bar); -- Ausgabe: 5;
- -- 'bar' Bleibt trotzdem auf diese Datei beschränkt lokal
- [/lua]
- Wichtig ist zu sagen, dass in Lua JEDE Variable lokal gesetzt werden kann. Es gibt keine Variable, welche nicht Lokal sein kann.
- [lua]
- local foo = "bar"; -- Lokaler String
- local foo_table = {} -- Lokaler Table
- local foo_int = 5; -- Lokaler Integer
- local foo_boolean = false; -- Lokaler Boolean
- local foo_function = function() end; -- Lokale Funktion
- [/lua]
- Wie schon angemerkt kann man auch Funktionen lokal setzen. Solltet Ihr eine Funktion so definieren:
- [lua]
- function foo()
- return "bar"
- end
- [/lua]
- So wird die Funktion "foo" Global erstellt und ist im kompletten Script erreichbar.
- Ausserdem kann folgende Situation gegeben sein:
- [lua]
- function joinHandler() -- Globale funktion
- end
- addEventHandler("onPlayerJoin", getRootElement(), joinHandler)
- [/lua]
- In diesem Beispiel wurde die Funktion joinHandler Global erstellt, welche jedoch nur von dem Event "onPlayerJoin" benutzt wird.
- Diese Funktion Global zu stellen ist somit kompletter Bullshit, da sie von keinem anderen Teil des Scriptes benutzt wird oder werden sollte.
- Im schlimmsten Fall kann es sogar sein, dass diese Funktion in der Laufzeit von einer anderen Funktion ueberschrieben wird.
- Dies kann man verhindern, indem man die Funktion von Anfang an schon lokal deklariert.
- [lua]
- local function joinHandler() -- Lokale Funktion, beschraenkt auf diese Datei
- end
- -- Auch moeglich:
- local joinHandler = function()
- end
- addEventHandler("onPlayerJoin", getRootElement(), joinHandler)
- [/lua]
- Somit kann man schonmal das Schlimmste Verhindern.
- Dieses Beispiel beschraenkt sich uebrigends nicht nur auf Funktionen.
- Nehmen wir ein Beispiel an der Variable Houses.
- 'Houses' ist eine Tabelle welche saemtliche Informationen, Elemente und Daten zu jeden Haeusern auf dem Server enthaelt.
- [lua]
- Houses = {}
- local function createHouse(iID, sHausName)
- Houses[iID] = sHausName;
- end
- createHouse(1, "Beispielhaus 1");
- createHouse(2, "Beispielhaus 2");
- [/lua]
- Die Variable Houses ist Global und kann von jedem Standort des Gamemodes erreicht werden.
- Nehmen wir mal das Schlimmste vom Schlimmsten an und sagen, dass diese Variable ungefaehr 2000 Haeuser besitzt.
- In dieser Variable befinden sich Event-Handler, Pickup-Elemente, Funktionen, Methoden, Attribute und MySQL Speicherbefehle.
- (Instanzen von Haeusern zum Beispiel)
- In einer Funktion schreibt Hans Peter folgendes:
- [lua]
- addCommandHandler("kaufehaus", function(uPlayer)
- local Geld = uPlayer:getMoney(); -- Lokale Geldvariable
- local Houses = uPlayer:getHouses(); -- Lokale Hausvariable
- if(#Houses < 1) then -- Besitzt der Spieler schon ein Haus?
- -- Code
- else
- uPlayer:outputChatBox("Du hast bereits ein Haus!");
- end
- end)
- [/lua]
- Schreibt Hans Peter nun die Variable 'Houses' ohne den 'lokal' Prefix:
- [lua]
- addCommandHandler("kaufehaus", function(uPlayer)
- local Geld = uPlayer:getMoney(); -- Lokale Geldvariable
- Houses = uPlayer:getHouses(); -- Globale Hausvariable, Schwupps - Ueberschrieben!
- if(#Houses < 1) then -- Besitzt der Spieler schon ein Haus?
- -- Code
- else
- uPlayer:outputChatBox("Du hast bereits ein Haus!");
- end
- end)
- [/lua]
- Hat er die gesammte Haustabelle des Servers ueberschrieben.
- Die Haeuser koennen somit nie wieder in der Laufzeit erreicht werden.
- Was folgen wird sind Fehler, welche dafuer sorgen werden dass Wahrscheinlich das Gesammte Gamemode neugestartet werden muss.
- Dieses Problem existiert meist nur in Lua weshalb man hier besonderst auf diesen Fehler achten sollte und ihn niemals unterschaetzen sollte.
- In anderen Programmiersprachen existiert hierfuer das Schluesselwort "Protected". So kann eine Ueberschreibung verhindert werden.
- Dieses Problem kann man in Lua jedoch verhindern, indem man eine Managerklasse fuer die Haeser schreibt.
- Die Managerklasse enthaelt eine Klassenvariable welche die Daten der Haeuser sicher speichert. Da die Klasse mit einem getInstance() aufgerufen wird, ist eine Ueberschreibung sehr gut zu verhindern.
- (Selbstverstaendlich kann man diese Variable auch ueberschreiben, aber an sowas denkt man und macht es nicht aus versehen.)
- Die Globale Umgebung von Lua (_G)
- Die Globale Umgebung von Lua wird auch die _G Variable genannt.
- [lua]
- _G
- [/lua]
- In dieser Variable befinden sich alle globalen Variablen.
- Wie man genau diese Umgebung benutzen kann, moechte ich ungerne Ansprechen da es fuer die meisten hier eventuell zu Komplex sein wird.
- (Stichwort setfenv)
- Diese Umgebung wird von MTA zur Speicherung der globalen Variablen verwendet.
- Globale Variablen in der Umbebung sind beispielsweise Funktionen wie "getPlayerName" oder "getElementData", aber auch Variablen wie "root" oder "localPlayer".
- Ich kann nicht mehr als Betonen, wie sehr man die Finger von dieser Umgebung lassen sollte. Diese Umbebung wird intern von
- MTA stets verwendet und man sollte niemals, nie und nimmer irgendwelche sinnlosen Variablen in dieser Globalen Umgebung speichern.
- Es gibt viele Personen, welche so ziemlich jede Elemente die sie erstellen in dieser Umgebung einspeichern.
- Entweder haben diese Personen nicht mehr alle Tassen im Schrank oder sie folgen ein Scriptingstyle einer diversen Person,
- welche vor 6 Jahren kein blassen Schimmer von dem hatte, was sie eigentlich tat.
- Der Grund dieser Person war schlichtweg unwissenheit.
- Im schlimmsten Fall kann das Script nicht mehr laufen, man ueberschreibt wichtige Variablen oder es laeuft sehr langsam, da die Umgebung zu Zugestopft ist.
- Fakt: Diese Variable ist nicht zur Speicherung von Gamemodedaten oder Elementen vorhanden, sondern hat einen eigenen Zweck.
- Zur not kann man stets eine eigene Umbebung erstellen: (Am besten mit einer Managerklasse)
- [lua]
- Umgebung_ {}
- Umgebung_.foo = "bar";
- Umgebung_["Fahrzeug_5"] = Vehicle(...);
- [/lua]
- Aber bitte nicht in der _G Umgebung.
- In der Methode oben enthaelt die _G Umgebung automatisch die 2. Umbebung. Solltet ihr die _G Umgebung manipulieren, manipuliert ihr auch die 2. Umgebung.
- Nur weil eine Variable blau markiert wird, heisst es nicht dass sie automatisch die beste und Performanteste Moeglichkeit ist.
- Da dieses Missverstaendnis abschliessend erklaert wurde, moechte ich mich bei all denen Bedanken, die dieses Tutorial durchgelesen haben.
- Sollten Fehler, Unwissenheit, oder falsche Angaben angegeben wurden, so bitte ich euch eure Meinung und Fehler zu berichten.
- Ich werde anschliessend den Fehler beheben.
- Falls noch Fragen offen sind, koennen diese auch gerne gefragt werden.
- Mit freundlichen Gruessen
- Noneatme
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement