env hook in lua

  • Oh man da ist es doch schon fast wieder 4 Monate her seit dem Letzen Post aber naja ( *das war's dann mit der Vorstellung jede Woche ein post* ), aber nun gut..
    Also um was soll es im nächsten Abschnitt gehen ?
    -Lua environment (env)
    Was ist das ?
    Nun eine Env ist der Kontext aus dem Funktionen ausgeführt werden ( normale ist es _G ).
    Nun alles was man global anlegt kommt in die Env,
    a = 1 ist das selbe wie _G.a = 1  ebenfalls könnte man auch durch die dafür vorgesehen Setter und getter so bekommen:getfenv( 1 ).a 
    im folgenden werde ich euch demonstrieren wie man funktionene hooken kann ohne die Funktion zu Detouren ( hooken bedeutet das man seine eigene Funktion zwischenschalten kann )
    das erste was wir brauchen ist die Globaletabelle da wenn wir eine eigene Env anlegen es keine funktionen kennt da sie nicht bekannt sind.
    im beispiel werde ich die ENV mit ev bezeichnen.


    C
    local env = { } //unsere env tabelle




    wenn man jetzt die Enviroment auf ev setzt so würde es keine fuktionen wie string oder table etc. geben da (bei der Orginalen geht das da die Zugriffe auf string etc über _G erfolgt ) sie der Env nicht bekannt sind also um dies zu verhindern gibt es 2 möglichkeiten
    1. Die env auf eine Kopie von _G setzen ( so kennt sie von sich aus alle Funktionen )
    2. Der env eine Refferenz auf _G geben ( so kann man z.b env.g = _G und in der env g["string"]["..."] benutzen )



    Da wir das Hooking über eine Metatabelle machen werden, fällt die erste Lösung weg da wir sonst die meta Methode __index nicht benutzen können (zu Metatabellen werde ich in einem anderen post kommen).
    Ich möchte klarstellen, dass das hier nur ein Proof of concept ist und ich daher dies nur mit der _G Tabelle mach und deren direkten Indexen ( also _G.print aber nicht _G.string.len ) es ist zwar möglich macht es aber nur unnötig kompliziert (im beispiel).



    also zurück zum Thema wir brauchen _G für alle Funktionen die uns Lua zu verfügung stellt.


    Code
    local ev = { g = table.Copy( _G ) } // unsere env mit einer Koßie von g


    nun zur Veranschaulichung werde ich zeigen was passiert wenn wir in eine Env etwas schreiben

    Code
    local ev = { g = table.Copy( _G ) , print = print , getfenv = getfenv}//ich gebe der env ein par funktionen die ich brauche
    setfenv( 1 , ev)          // setzen der env
    a = 1                     // test var
    print( a )                // 1
    print( ev.a )             // 1
    print( getfenv(0).a )     // nil
    print( getfenv(1).a )     // 1
    print( _G.a )             // error _G undef


    nun ich hoffe das war bis jetzt verständlich... also nun weiter wir geben unserer env eine meta Tabelle


    also nun haben wir die metatabelle die müssen wir noch auf unsere Env setzen hier der volle Code:


    wenn man die Env global macht ist es so super einfach für verschiedene Scripte zusammen zu arbeiten bzw. lokale weiterzugeben


    ich hoffe es ist verständlich wenn nicht konstruktive Kritik gerne gesehen genauso wie fragen / Verbesserungsvorschläge.


    <3 K03 <3