Warum ist Local Scriptvariable durch eine Func(ohne ByRef) änderbar?

  • Hallo allemaal!
    Ich habe eine als Local im Script deklarierte Variable.
    Warum gilt sie in einer Function, wenn sie doch gar nicht Global ist?
    Und warum kann sie dort so verändert werden, dass sie den neuen Wert auch außerhalb annimmt?
    Das dürfte nach meinem bisherigen Verständnis doch nur bei einer ByRef-Übergabe möglich sein.

    Spoiler anzeigen
    [autoit]


    Opt("MustDeclareVars", 1)
    Local $Zahl = 111

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, "Vor Funktionsaufruf", "Zahl alt = " & $Zahl) ;liefert 111
    TestFunktion()
    MsgBox(48, "Nach Funktionsaufruf", "Zahl verändert = " & $Zahl) ;liefert 999 !?
    Exit

    [/autoit] [autoit][/autoit] [autoit]

    Func TestFunktion()
    $Zahl = 999
    EndFunc

    [/autoit]


    Das interessiert mich sehr, denn es betrifft die fernwirkungsfreie Programmierung...

    MfG ThPfund

    "Es könnte alles so einfach sein..."

    Einmal editiert, zuletzt von ThPfund (23. Oktober 2009 um 00:32)

  • Das ganze ist in Autoit etwas komisch. Anfangs ganz gut, da man kaum Fehler machen kann, aber naja ... wirds so klar?

    [autoit]


    Opt("MustDeclareVars", 1)
    Global $Zahl = 111 ;Lokale Deklaration ist außerhlab der Funktion unsinnig.

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    MsgBox(0, "Vor Funktionsaufruf", "Zahl alt = " & $Zahl) ;liefert 111
    TestFunktion()
    MsgBox(48, "Nach Funktionsaufruf", "Zahl verändert = " & $Zahl) ;wie man sieht bleibt die Lokale nur innerhalb der Funktion aktiv (wir anschließend aus dem Speicher gelöscht)

    [/autoit][autoit][/autoit][autoit]

    MsgBox(48, "Nach Funktionsaufruf", "Zahl verändert = " & TestFunktion2()) ;Return gibt die Zahl trotzdem zurück
    MsgBox(48, "Nach Funktionsaufruf", "Zahl verändert = " & $zahl) ; alles klar?
    Exit

    [/autoit][autoit][/autoit][autoit]

    Func TestFunktion()
    local $Zahl = 999
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    Func TestFunktion2()
    Local $zahl = 999
    return $zahl
    EndFunc

    [/autoit]
    • Offizieller Beitrag

    Dieses Verhalten 'sollte' eigentlich nicht auftreten. :S

    Aber um dein Problem zu lösen, sollte es doch reichen, Variablen in einer Funktion auch immer dort als Local zu deklarieren, es sei denn du verwendest Globale Variablen. Dann treten keine ungewollten Wechselwirkungen auf.

  • hab mal einen Auszug aus der deutsch Hilfe:

    Zitat

    Gültigkeitsbereich
    Der Gültigkeitsbereich einer Variablen wird gesteuert durch die Tatsache, wann und wie man die Variable deklariert. Deklariert man eine Variable am Anfang eines Skripts und außerhalb von Funktionen, existiert sie in dem Gültigkeitsbereich Global und kann von überall aus dem Skript gelesen oder geändert werden.

    Deklariert man eine Variable innerhalb einer Funktion, befindet sie sich in dem Gültigkeitsbereich Local und kann nur innerhalb dieser einen Funktion genutzt werden. Variablen, die innerhalb einer Funktion erstellt wurden, werden automatisch am Ende dieser Funktion zerstört.

    Werden Variablen über Dim deklariert oder innerhalb einer Funktion zugewiesen, haben sie standardmäßig den Gültigkeitsbereich Local, es sei denn, es gibt eine globale Variable des selben Namens (in diesem Fall wird die globale Variable verwendet). Dies kann geändert werden, indem man die Schlüsselwörter Local und Global benutzt, um Variablen zu deklarieren, und um so den gewünschten Gültigkeitsbereich zu erzwingen.

    MfG Schnuffel

    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

    ein paar Infos ...

    Wer mehr als "nur" Hilfe benötigt, kann sich gern im Forum "Programmieranfragen" an uns wenden. Wir helfen in allen Fällen, die die Forenregeln zulassen.

    Für schnelle Hilfe benötigen wir ein ! lauffähiges ! Script, dass wir als Demonstration des Problems testen können. Wer von uns erwartet ein Teilscript erstmal lauffähig zu bekommen, der hat
    1. keine wirkliche Not
    2. keinen Respekt vor Menschen die ihm in ihrer Freizeit Ihre Hilfe anbieten
    3. oder ist einfach nur faul und meint wir coden das für ihn

    In solchen Fällen erlaube ich mir, die Anfrage einfach zu ignorieren. ;)

  • Wäre es nicht konsequenter die lokale Deklaration außerhalb von Funktionen nicht zuzulassen?
    Irgendwie kann man machen was man will, bei Dim ists ähnlich.

    Die lokale bzw. globale Deklaration soll ja nicht willkürlich sondern mit Hintergrund erfolgen.

  • ich perönlich umgehe solche Probleme, indem ich innerhalb von Funktionen
    Local einmalige Variablennamen verwende.

    Man verliert sowieso die Übersicht, wenn man für 2 unterschiedliche Aufgaben
    die selben Variablennamen verwendet...

    MfG Schnuffel

    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

    ein paar Infos ...

    Wer mehr als "nur" Hilfe benötigt, kann sich gern im Forum "Programmieranfragen" an uns wenden. Wir helfen in allen Fällen, die die Forenregeln zulassen.

    Für schnelle Hilfe benötigen wir ein ! lauffähiges ! Script, dass wir als Demonstration des Problems testen können. Wer von uns erwartet ein Teilscript erstmal lauffähig zu bekommen, der hat
    1. keine wirkliche Not
    2. keinen Respekt vor Menschen die ihm in ihrer Freizeit Ihre Hilfe anbieten
    3. oder ist einfach nur faul und meint wir coden das für ihn

    In solchen Fällen erlaube ich mir, die Anfrage einfach zu ignorieren. ;)

    • Offizieller Beitrag

    Wäre es nicht konsequenter die lokale Deklaration außerhalb von Funktionen nicht zuzulassen?
    Irgendwie kann man machen was man will, bei Dim ists ähnlich.


    Meiner Meinung nach wäre wirklich konsequent, wenn Dim gestrichen wird und Local auch Local bedeutet. Also immer nur im aktuellen Deklarationsraum wirksam. Das würde sämtliche Irritationen ausschließen.

  • Danke für Eure Antworten! :)
    Ich habe gelernt, dass eine im Hauptscript mit Local deklarierte Variable trotzdem Global angelegt wird.
    Local greift nur innerhalb von Functions.
    Die Lösung meines Problems ist daher einfach:
    Das Hauptscript wandert in eine Func Main(), von der aus dann die anderen Functions aufgerufen werden.
    Jetzt kommt bei dem Versuch, die Variable anzusprechen (zum Beispiel aufgrund unbeabsichtigter Doppelbenennung)
    eine Fehlermeldung.
    Die Frage war übrigens aufgetreten, als ich zum erstenmal mit einer eigenen UDF experimentiert habe.
    Und in der UDF möchte ich ja eigentlich nicht, dass plötzlich irgendwelche Variablen aus dem aufrufenden Script mitmischen...

    MfG ThPfund

    "Es könnte alles so einfach sein..."