Seite 1 von 2

PB dröselt Parameter von hinten auf?

Verfasst: 25.01.2006 20:36
von AND51
Hallo!

Ausgehend von dieser Codezeile möchte ich mal was fragen:

Code: Alles auswählen

server=OpenNetworkConnection(InputRequester("Ziel", "IP, Hostnamen oder Domain eingeben:", ""), Val(InputRequester("Port", "An welchen Port ein Server aufmachen?", "")))
So. Es geht hier nicht um eine konkrete Frage zu einem konkreten Problem, sondern: Wenn ihr diese Zeile kompiliert (mit InitNetwork(), of course), dann werdet ihr feststellen, dass erst nach dem Port und dann nach dem Ziel gefragt wird.
Warum ist das so?
Ich bin auf das Problem gestoßen, als ich mich das erste mal mit CreatePack() und Co. von PB beschäftigt habe. Ich habe in Googles Cache folgendes gefunden:
gimbly hat geschrieben:Habe gerade den merkwürdigen Effekt festgestellt, dass

Code: Alles auswählen

WriteData(NextPackFile(),PackFileSize()) 
oft nicht funktioniert, manchmal aber schon(?).

Dagegen funktioniert folgendes immer:

Code: Alles auswählen

file=NextPackFile() 
WriteData(file,PackFileSize()) 
Ist also die bessere Alternative.
http://66.249.93.104/search?q=cache:xtx ... =clnk&cd=2
OK, deswegen habe ich mir fast umsonst meine Haare vor Wut vom Kopf gerissen ;-) weil ich die ganze Zeit rumprobiert habe, warum das nicht geht: Eine inkludierte Datei PB-Entpacken und in eine Datei speichern.
Warum geht das obige Beispiel nicht? Nun, PackFileSize() liefert die Dateigröße der Datei, die NextPackFile() zurückgibt. Da PB aber anscheinend alle Parameter von hinten "aufdröselt" kann das obere Beispiel nicht funktionieren, sondern erst das zweite. Denn da wird ja erst NextPackFile() aufgerufen, sodass die zweite Funktion problemlos die Größe zurückgeben kann.
Ist das bei anderen Befehlen oder gar allen Befeheln genauso? Wie oben gezeigt, habe ich das bisher bei OpenNetworkconnection() festgestellt.
Arbeite PB bei If auch von rechts nach links? Wenn ja (oder auch nein), was ist, wenn ich, wenn's klappt, erst eine Datei erstellen will und dann die Datein reinschreiben will? geht dann

Code: Alles auswählen

If CreateFile(1, "C:\MyDatei.txt") And WriteData(*buffer, 4097)
etwa in die Hose, weil er erst die Daten zu schreiebn versucht und dann überprüft, ob die Datei korrekt angelegt wurde?
Mit dieser "Tatsache" will ich niemanden anprangern, ich möcht' das "Phänomäen" einfach nur lüften...

Verfasst: 25.01.2006 23:14
von Icke
Warum ist das so?
Weil die Funktion "OpenNetworkConnection" so vom Programmierer programmiert ist 8) ! Sicher hätte man das auch anders machen können, aber ich muss sagen das ich selber z.B. nie auf die Idee kommen würde so eine Connection zu erstellen. Ich mit meinen einfachen Gehirnwindungen lege vor dem erstellen einer Verbindung fest zu welcher Adresse und zu welchem Port ich verbinden will. Also so :

Code: Alles auswählen


Server$=InputRequester("","Server","")

Port=Val(InputRequester("","Port",""))

If InitNetwork() And Port>0 And Server$<>""

  ConnectionID=OpenNetworkConnection(Server$,Port)
  
...


Ein entscheidender Vorteil dabei ist auch, das ich vorher überprüfen kann ob die Eingaben gemacht wurden, denn ohne einen der beiden Werte kann keine Verbindung zustande kommen. Sollte man auf jedenfall berücksichtigen.

Verfasst: 25.01.2006 23:37
von Deeem2031
Es ist Standard das die Parameter von hinten nach vorne gepusht werden - das hat nichts mit der Procedure selber zu tun. "If" und der gleichen arbeitet aber warscheinlich von links nach rechts da nichts auf den Stack gepusht wird.
Aber es ist sowieso schlechter Code wenn man sich darauf verlässt das der Code innerhalb einer Zeile in einer bestimmten Richtung ausgeführt wird.

Verfasst: 26.01.2006 08:34
von AND51
Ja, ihr habt ja recht, man sollte immer erst überprüfen - aber ich bin halt nicht der Typ, der einzeln InitNetwork(), OpenWindow() und CreateGadGetList() in eine If-Abfrage packt, um alles haarklein zu kontrollieren.
Ich bin hier jetzt einfach mal vom Idealfall ausgegangen bei der Connection.
Oben würd ich einfach fragen:

Code: Alles auswählen

If server
   Debug "Verbindung ok."
EndIf
Das war's (für mich jedenfalls).

Nun, wie oben erwähnt ist dieses Problem bei WriteData() und NextPackFile() natürlich ein bisschen doof, aber was soll man machen... SO weiß ich (und andere) wenigstens jetzt, warum's manchmal nicht funktionieren könnte, wenn wieder ein "unerklärlicher" Fehler auftaucht.

Verfasst: 26.01.2006 09:39
von nco2k
@AND51
> Network Port
ja natürlich prüft er zuerst den port, würde ich auch nicht anders machen. er muss ja zuerst einen port "öffnen" bevor er die verbindung versucht aufzubauen.

> WriteData(NextPackFile(), PackFileSize())
das das so nicht einfach geht ist auch logisch, wenn NextPackFile() nicht geklappt hat würde er ja auch den letzten aktuellen PackFileSize() (wenn überhaupt) zurückgeben. ausserdem muss er ja anhand der grösse 1.) schauen ob diese auch gültig ist und 2.) den speicherbereich dementsprechend "anpassen".

> If CreateFile(1, "C:\MyDatei.txt") And WriteData(*buffer, 4097)
das ist was anderes, wenn If CreateFile() (<> #False) nicht geklappt hat, wird er die "zeile" nicht weiter fortsetzen.

> ...aber ich bin halt nicht der Typ...
das ist keine frage vom typ sein, sondern eher von funktionierender schreibweise und weniger bzw. nicht funktionierender schreibweise. solange alles klappt ist ja alles in ordnung aber wenn ein fehler auftritt, dann ist das automatisch ein unaufhaltsamer kettenunfall. in der fertigen exe hast du später keinen debugger mehr, der den fehler abfängt, deswegen lieber selber während dem coden schon rechtzeitig die notbremse einbauen. in pb lässt sich so ziemlich alles prüfen und diese möglichkeit sollte man auch nützen. :allright:

edit: ausserdem kann man nicht pauschal sagen, dass alles von hinten nach vorne überprüft wird, es ist eher eine designfrage:

Code: Alles auswählen

Procedure TestXYZ(A, B, C, D)
  If B = 1
    If D = 1
      If C = 1
        If A = 1
          ProcedureReturn #True
        Else
          Debug "A <> 1"
        EndIf
      Else
        Debug "C <> 1"
      EndIf
    Else
      Debug "D <> 1"
    EndIf
  Else
    Debug "B <> 1"
  EndIf
  ProcedureReturn #False
EndProcedure

TestXYZ(0, 0, 0, 0)
es kommt immer auf die funktion drauf an, ich hätte genauso gut TestXYZ(B, D, C, A) schreiben können, was jedoch weniger nachvollziehbar wäre. aber die gewählte reihenfolge die der entwickler festlegt, hat meistens seine gründe. es ist imo einfach schöner die Parameter so zu haben MessageRequester("Überschrift", "Text", #MB_OK) anstatt MessageBox_(0, "Text", "Überschrift", #MB_OK) wo zuerst der text und dann die überschrift kommt. was intern abläuft braucht dich nicht wirklich zu interessieren, solange du immer schön fleissig alles überprüfst ob es auch geklappt hat. :wink:

c ya,
nco2k

Verfasst: 26.01.2006 11:19
von Deeem2031
nco2k hat geschrieben:@AND51
> Network Port
ja natürlich prüft er zuerst den port, würde ich auch nicht anders machen. er muss ja zuerst einen port "öffnen" bevor er die verbindung versucht aufzubauen.
Das hängt doch überhaupt nich damit zusammen welche parameter die Procedure zuerst braucht, die Parameter werden sowieso gleichzeitig an die Proc weitergegeben.
Wenn die Proc OpenNetworkConnection(Port,IP.s) heißen würde, dann würde er zuerst die IP abfragen und das is (zumindest bei PB) immer so das der letzte Paremeter zuerst bearbeitet wird.

Verfasst: 26.01.2006 11:54
von nco2k
@Deeem2031
> die Parameter werden sowieso gleichzeitig an die Proc weitergegeben
natürlich, aber eben nacheinander ausgewertet.

> OpenNetworkConnection(Port,IP.s)
auch wenn der befehl OpenNetworkConnection(Port,IP.s) heissen würde, glaube ich, dass er trotzdem zuerst nach dem port schaut. auch hier baut pb auf die api befehle auf (in diesem fall WSOCK32) und afaik muss dort der port zuerst verifiziert werden. wie es bei den anderen sachen ist, kann ich nicht beurteilen.

kannst ja fred fragen, was nun stimmt. :D

c ya,
nco2k

Verfasst: 26.01.2006 16:43
von Deeem2031
nco2k hat geschrieben:@Deeem2031
> die Parameter werden sowieso gleichzeitig an die Proc weitergegeben
natürlich, aber eben nacheinander ausgewertet.
Ja, klar.. immer von hinten nach vorne, das ist völlig unabhängig von der Procedure.
nco2k hat geschrieben:kannst ja fred fragen, was nun stimmt. :D
Brauchst du nicht, ich hab eh Recht :P

Verfasst: 26.01.2006 16:46
von MVXA
> Brauchst du nicht, ich hab eh Recht :P
Regel Nr. 1: Deeem hat immer Recht
Regel Nr. 2: Im Zweifelsfalle siehe Regel Nr. 1
oder wie <_<?

Verfasst: 26.01.2006 17:04
von Deeem2031
Mir gings nur langsam auf'n Keks das er nicht einsehen will dass, das immer so ist und nicht nur weil er angeblich den Port zuerst braucht.