Seite 3 von 4

Verfasst: 10.05.2006 19:57
von Kaeru Gaman
nicht über den sinn...

aber den knackpunkt habe ich persönlich erst durch jears präzise darlegung erkannt.

Verfasst: 11.05.2006 03:23
von Toshy
@real
genau. damit wird nur "der Zugriff" auf die Variable erlaubt.

@jear
das Was du meinst ist wohl "static". "Static" dient dazu was du meintest.

@all
Mich interssiert das auch, aber ich sehe hier keinen Fehler.
Shared gibt den Zugriff innerhalb einer Procedure auf eine Variable außerhalb der Procedure frei. Sie "declariert" keine Variable. Existiert sie vorher nicht, so gibt es einen Fehler.
sTemp.s im Hauptprogramm und Shared sTemp.s in einer Prozedur dürften keinesfalls die gleiche Variable meinen!

Gäbe es eine zweite Prozedur mit Shared sTemp.s wäre der Mechanismus von Shared ausgehebelt.
Natürlich dürfen sie das. GENAU das ist der Zweck von Shared.
Wenn du nun willst, das eine von der Procedure verwendete Variable zwar "geshared" wird, aber nicht mit der "übergeordneten", sondern nur von der selben Procedure aufgerufenen, dann mußt du das dafür vorgesehene "static" verwenden. Vergleich mal beides. Das ist kein Fehler, sonder gewollt.

Wenn sich zwei Prozeduren eine Variable teilen wollen, dann müsste diese gegen alle Deklarationen abgeschottet sein, die nicht an diesem Verbund teilnehmen.

Die jetzige Implementierung von Shared in PB ist unsinnig und wenig wert, denn sie erlaubt keine privaten Variablen über Prozeduren hinweg.
Insofern ist Shared jetzt nur ein schlechteres Global. Kein Programmteil kann der Integrität von Variablen sicher sein. Das aber wäre es, was Shared ausmachen sollte.
Wie gesagt, static soll an sich dafür dienen. Zwar ist "shared" eine Art von inversem global, aber es macht schon sinn.
Ein "shared" das "nur für ALLE PRoceduren", außer dem "Maincode" funktioniert, würde wohl mehr probleme bringen. Dann auch das wäre nur eine Ersatz für Global, wo dann einfach nur der "MAincode" auf "protected" gesetzt ist. Und man würde kann ja nicht bestimmen für welche Proceduren das shared gilt, also müßte das für alle sein und das ist wiederum gefährlich bzw. man müßte dann oft protected verwenden.

Code: Alles auswählen

 Global s.s
s = "Hauptcode" 
  
Procedure Change()
   Static a
   Static s.s
   a+1
   s = s + " " + Str(a)
   Debug "In Procedure: "+s 
EndProcedure 
  
Change()
Change()
Change()
Debug s 
So klappt es doch wunderbar.

[edit]
ach ja, was meinst du mit
Nein, test = kann keine Variable definieren.
Es ist vielmehr das erste Shared, das die Variable test definiert.
Das folgende Beispiel führt schließlich zum Fehler bei der Übersetzung.
Natürlich declariert das erste "test" die Variable und belegt sie mit dem Inhalt. Nur darfs du nicht den Fehler machen und dort vergessen, den Variablentyp anzugeben.

Code: Alles auswählen

Declare.s eins() 
Declare.s zwei() 
test.s = "Aufrufe : " ; bersetzungsfehler ! 

Debug test 

eins() 
Debug test 

zwei() 
Debug test 
  
End 

Procedure.s eins() 
   Shared test.s 
   test + " eins war dran" 
EndProcedure 

Procedure.s zwei() 
   Shared test.s 
   test + " und zwei war dran" 
EndProcedure
Läuft bei mir einwandfrei, was soll daran denn angeblich nicht laufen?

Gruß
Toshy

Verfasst: 11.05.2006 08:35
von jear
@Toshy
Ich kann Dir nur raten, Deinen Beitrag nochmals gut durchzulesen und mit seiner Vorgeschichte abzugleichen.

Static definiert eine lokale Variable, die außerhalb der vereinbarenden Prozedur unbekannt ist. Sie kann also Shared im eigentlichen Sinne nicht ersetzen. Wie soll auf eine Static aus einer anderen Prozedur zugegriffen werden?

Code: Alles auswählen

Procedure eins()
  Static test.s
  test + " eins war dran"
  Debug test
EndProcedure

Procedure zwei()
  Static test.s
  test + " zwei war dran"
  Debug test
EndProcedure

eins() : eins() : zwei() : zwei() : eins() : zwei()
Wo ist hier eine "Shared"-Wirkung?

Shared definiert eine Variable, die in allen Prozeduren bekannt ist, in denen sie mit Shared definiert ist. Außerdem ist sie im Hauptprogramm definiert, wenn die Definition als Shared in einer Prozedur aus der Sicht des Compilers vor der ersten Ansprache im Hauptprogramm stattgefunden hat. Ist dies nicht der Fall (siehe mein zweites Beispiel), dann ist die Variable auch im Hauptprogramm unbekannt.

Natürlich weiß ich, wie Shared zur Zeit implementiert ist. Steht ja auch alles in der Hilfen. Nur macht zur Zeit (siehe Absatz davor) seine Verwendung kaum einen Sinn, weil sie sich von der Wirkung einer Vereinbarung mit Global nur marginal unterscheidet.

Ich zumindest würde mir wünschen, dass Shared explizit zur Variablendefinition benutzt werden muss, wenn sich zwei oder mehr Programmkörper (Main, Prozeduren) eine Variable "teilen" sollen.

Verfasst: 11.05.2006 16:53
von Toshy
@jear.
Es ist doch eh nur eine Sprachdefinition. Global und Shared sind im Grunde das selbe von der Funktion her, aber nur fast. Da sind wir uns ja einig. Static ist wie du sagst auf die selbe Procedure begrenzt, stimmt schon, aber sobald du unterschiedliche Procedure(namen) nutzt geht das nur über eine "quasi Globale". Auch das von dir gewünschte Shared ist nichts weiter als eine (verkappte) Globale, anders geht es ja nicht.

Um Parameter von einer Procedure in einer anderen nutzen zu können kann man diese nur direkt beim AUfruf übergeben oder indem man den selben Speicherbreich nutzt (also allocatememory oder ne Variable). Dieser Speicherbreich ist natürlich im Grunde wie eine Globale, nur die Adresse wird halt nur den jeweiligen Proceduren mitgeteilt.
Und genau das macht doch shared. Nur wie du schon sagst, ist auch im "Hauptcode" die Variable immer bekannt. Das ist das einzige was wenn ich dich richtig verstehe dich aufregt, sonst ist es das was du willst.
Wo ist hier eine "Shared"-Wirkung?

Shared definiert eine Variable, die in allen Prozeduren bekannt ist, in denen sie mit Shared definiert ist. Außerdem ist sie im Hauptprogramm definiert, wenn die Definition als Shared in einer Prozedur aus der Sicht des Compilers vor der ersten Ansprache im Hauptprogramm stattgefunden hat. Ist dies nicht der Fall (siehe mein zweites Beispiel), dann ist die Variable auch im Hauptprogramm unbekannt.
Na da. Hast es doch selber erklärt und ich doch auch. Der einzige Unterschied ist, das die sharedvariable immer im Hauptcode bekannt ist bzw. dort erst declariert sein muß (als lokalte Variable).
Und wenn du dieses Beispiel von dir meinst

Code: Alles auswählen

Declare.s eins() 
Declare.s zwei() 

test = "Aufrufe : " ; Übersetzungsfehler ! 

eins() 
Debug test 

zwei() 
Debug test 
  
End 

Procedure.s eins() 
  Shared test.s 
  test + " eins war dran" 
EndProcedure 

Procedure.s zwei() 
  Shared test.s 
  test + " und zwei war dran" 
EndProcedure
dann ist das doch der Code den auch ich dir oben nochmal aufgezeigt habe. Und der geht immer. Im Hauptcode ist die Variable IMMER bekannt (auf jedenfall bei meinen Tests). Du hattest nur einfach einen Fehler im Code, du hast im Haupcode vergessen der Variablen Test den Typ "String" zuzuordnen.
Dein

Code: Alles auswählen

test = "Aufrufe : " ; Übersetzungsfehler ! 
erstellt hier keine String mit dem Inhalt "Aufruf", sondern die Variable Test in Form eines Longs (oder Bytes, weis nicht genau). Bei mir gibt es da eh eine Fehlermeldung. Nimm man aber String.s, dann klappt es doch.

Da wo du natürlich recht hast ist, das es schon angenehmer wäre, so wie du es wünscht, denn der einzige Unterschied wäre, das die Variable dann nicht automatisch im Haupcode bekannt wäre, sonder auch erst, wenn man dort "sharde" nutzt bzw. als "Ersatz" im Hauptcode "Protected" erlaubt wäre. Einzig das der Hauptcode nicht wie eine Procedure gehandhabt wird (im Verhalten der Variablen) macht den Unterschied aus. Und das dürfte so "unschön" das auch ist, wohl kein Problem sein.

Von meinem Verständis her, aber kann es kaum anders sein, denn das "shared" muß ja eine Variable zur Basis haben und das kann nur die Variable aus dem Hauptcode sein oder die Variable die zu erste "shared" aufruft. Fred hat sich für die Variable im Hauptcode entschieden, warum auch immer. Aber ich vermute, das liegt daran, das dadurch verhindert wird, das "shared" ind "global" bei der selben Variable in Konflikt treten.

Grüßle
Toshy
ps. Unterschiede zwischen PB3.94 und PB4 nicht groß ausgetestet.

Verfasst: 11.05.2006 22:24
von ullmann
Ich finde das Verhalten des Compilers korrekt (wie in der Hilfe beschrieben) und die derzeitige Implementierung von Shared gut.
Die mir bekannten Fälle der Variablenverwendung sind alle realisierbar:

Mit Global steht die Variable in der Main und in allen Prozeduren zur Verfügung, mit Protected kann ich in der Prozedur eine gleichnamige Variable unabhängig von (geschützt vor) der globalen Variablen verwenden.

Define kann im Main und in einer Prozedur stehen, damit können auch gleichnamige, aber voneinander unabhängige Variablen definiert werden. Ohne Option Explicit geht das auch ohne Define (Autodefine).

Mit Shared habe ich zwei Möglichkeiten:

1. Ich kann einen oder mehreren Prozeduren Zugriff auf eine Mainvariable gestatten (shared - Zugriff teilen), wenn z.B. von 40 Prozeduren nur 2 Prozeduren Zugriff erhalten sollen und auch erhalten, dann ist das schon ein erheblicher Unterschied zu globalen Variablen und

2. Eine Gruppe von Prozeduren kann Variable A, eine andere Gruppe von Prozeduren kann Variable B usw. gemeinsam nutzen. Dazu werden eben im Main die Variablen A und B definiert (und wenns so gewollt ist, nicht weiter im Main benutzt), sowie die entsprechenden Shared-Befehle in den Prozeduren. Wo ist das Problem?

Mit Static können mehrere Prozeduren auch gleichnamige, aber jeweils unabhängige Variablen definieren, die ihre Werte (unterschiedlichen Werte) für weitere Aufrufe jeweils behalten.

Was will man mehr?

Rainer

Verfasst: 12.05.2006 08:17
von ts-soft
Sinnvoller Einsatz von Shared Variablen ist eigentlich nur dort, wo ich diese
nicht als Parameter übergeben kann. Z.B. Callback, Init- und EndFunctionen
(betrifft DLL und UserLibs usw.) Ansonsten sollte man damit genauso
sparsam umgehen, wie mit Global. Lieber als Parameter übergeben! Bei
kleineren Projekten kann man dies natürlich auch vernachlässigen.

Verfasst: 12.05.2006 14:49
von MVXA
Benutze Shared eigentlich um das Verhalten einer Prozedur verändern
zu können, da die Prozedur eigentlich nicht vom eigenen Programm
ausgeführt wird.

Verfasst: 12.05.2006 18:30
von ullmann
@MVXA

Wenn die Prozedur nicht vom eigenen Hauptprogramm aus aufgerufen wird, könnte man ihr Verhalten über Shared-Variablen nur von einer anderen (eigenen) Prozedur aus steuern. Stimmt, für diesen Fall fehlt in PB ein Variablentyp. Gibt es den denn in anderen Programmiersprachen?

Rainer

Verfasst: 13.05.2006 09:43
von Kaeru Gaman
> Ansonsten sollte man damit genauso sparsam umgehen, wie mit Global. Lieber als Parameter übergeben!

das ist dein credo, das weiß ich schon.

aber ich finde, man sollte das nicht so generalisieren.

wenn ich z.b. zwei dutzend procs habe, die alle die mauskoordinaten verarbeiten sollen,
fände ich es reichlich unpraktisch, die jedesmal als argumente zu übergeben...

Verfasst: 14.05.2006 00:15
von ts-soft
Kaeru Gaman hat geschrieben:> Ansonsten sollte man damit genauso sparsam umgehen, wie mit Global. Lieber als Parameter übergeben!

das ist dein credo, das weiß ich schon.

aber ich finde, man sollte das nicht so generalisieren.

wenn ich z.b. zwei dutzend procs habe, die alle die mauskoordinaten verarbeiten sollen,
fände ich es reichlich unpraktisch, die jedesmal als argumente zu übergeben...
Ich meinte nur allgemeine Variablen, für sowas kann man StructureVariablen
nehmen, da sind dann Verwechslungen und Überschneidungen weitgehend
ausgeschlossen. Statt Global kann man diese auch einem Fenster, Object
oder Control zuordnen (SetProp_ oder SetGadgetData)