Prioritäten bei Variablen und Funktionen

22. Oktober 2008 16:02

Ich habe mich gerade überraschen lassen; vielleicht hindert es jemanden von euch daran, an Zukunft damit auf die Nase zu fallen.

Lokale vs. globale Variablen
Ich befinde mich in einer Funktion, in der eine lokale Variable TempSalesLine definiert worden ist.
Dieser Variablenname ist auch für eine globale Variable vergeben worden.
Welche Variable wird die Funktion nun ansprechen? Die lokale.

Reportfunktion vs. Tabellenfunktionen
Ich befinde mich in einem Report mit DataItem "Sales Line", Trigger OnAfterGetRecord.
Ich kopiere mir eine Funktion aus der Tabelle Sales Line in den Report, z.B. GetItem.
Welche Funktion wird angesprochen, wenn ich im Trigger GetItem ohne Recordvariable aufrufe? Die Funktion der Tabelle!!
Daher dringender Rat: Wenn ihr euch Funktionen für einen Report aus einer Tabelle kopiert/erstellt, verhindert gleichen Benennungen!

Variable vs. Feldname innerhalb WITH (Danke an Torsten67)
Code:
WITH Recordvariable DO BEGIN
  Name := 'abc';
END;
Gibt es sowohl eine Variable Name als auch Recordvariable.Name, so hat Recordvariable.Name Vorrang.

Re: Prioritäten bei Variablen und Funktionen

1. Juli 2009 09:57

Zu diesem Thema kann ich auch eine Erfahrung beisteuern.

Zuerst mein Erklärungsmodell, warum in Dataport- und Report-Triggern, bei denen automatisch der Funktionsparameter "Rec" deklariert ist, dieser die höchste Priorität besitzt:

In solchen Triggern wirkt automatisch ein unsichtbares WITH Rec DO BEGIN ...END.
Dieses hat die höchste Priorität, erst dann kommen lokale und globale Variablen und Funktionen.

Jetzt zu meinem eigentlichen Thema. Es gab Zeiten, da habe ich gern selbst mit der "WITH ... DO" Anweisung gearbeitet -- es sah sehr elegant aus und ich brauchte nicht so viel zu tippen.
Bis zu dem Tag, als ich recht lange nach der Ursache für einen Fehler suchen durfte. Nach einer unverfänglichen Anpassung spielte der Code verrückt. Es lag aber nicht an dieser Änderung, dass konnte sicher ausgeschlossen werden.

Was war passiert? Hier in etwa die Entstehungsgeschichte:

In einem Codeabschnitt wird mittels WITH auf eine bestimmte Tabelle zugegriffen. Innerhalb dieses WITH-Blocks wurde ebenfalls eine lokale Variable der aktuellen Funktion angesprochen, nennen wir die Variable meinetwegen "Value". Völlig unverdächtig ...

Die Zeit vergeht, Projekte kommen und gehen und irgendwann wünscht sich der Kunde ein paar zusätzliche Felder in einigen Tabellen. Auch in der oben genannten Tabelle wird ein neues Feld eingefügt -- wir nennen es "Value". Die neue Funktionalität wird getestet, alles funktioniert. Wrklich! Aber ist auch alles in Ordnung? Dem Schein nach ja ....

Wieder vergeht viel Zeit, wieder werden einige Erweiterungen nötig.

Diesmal ist das besagte Objekt mit der WITH Anweisung betroffen, es wird neu kompiliert --- und Peng!
Ab jetzt taucht der Fehler auf. Hier in der kurzen Schilderung ist klar, woran es liegt. Aber im waren Leben sah natürlich niemand diesen Fehler auf Anhieb, zumal dieser erst durch das Kompilieren "aktiviert" wurde.

Was habe ich daraus gelernt?

Seitdem verwende ich kein explizites WITH mehr. Lokale und Globale Variablen bekommen grundsätzlich abgekürzte Namen, Tabellenfelder dagegen immer ausgeschriebene, besser noch, aus mehreren Wörtern bestehende Namen.
Tabellenfunktionen, die nur lokal verwendet werden, bekommen auch das Property Lokal = Yes.

Re: Prioritäten bei Variablen und Funktionen

1. Juli 2009 10:59

Habe ich das richtig verstanden? Wenn ja, ergänze ich meinen Einganbsbeitrag um diesen Abschnitt:

Variable vs. Feldname innerhalb WITH
Code:
WITH Recordvariable DO BEGIN
  Name := 'abc';
END;
Gibt es sowohl eine Variable Name als auch Recordvariable.Name, so hat Recordvariable.Name Vorrang.

Re: Prioritäten bei Variablen und Funktionen

1. Juli 2009 11:02

Schön ist es auch wenn man eine eindeutige Record-Variable hat aber ein Feld dieses Records hat den gleichen Namen wie eine andere Variable ...
Da braucht man länger bis man herausgefunden hat, warum man einen Compiler-Fehler beim Filtern bekommt. :-|

Re: Prioritäten bei Variablen und Funktionen

1. Juli 2009 11:03

Sebastian Pfliegel hat geschrieben:Schön ist es auch wenn man eine eindeutige Record-Variable hat aber ein Feld dieses Records hat den gleichen Namen wie eine andere Variable ...

Genau darum ging es doch gerade - wenn ich nicht gerade völlig daneben liege ;-)

Aber das Ergebnis steht im Widerspruch ....
Das hier geht also nicht?
Code:
WITH Recordvariable DO BEGIN
  SETRANGE(Name, 'abc'); // Name als Variale hat Vorrang -> unzulässige Funktion
END;

(Habs getestet, das führt zu keinem Fehler, da auch hier Recordvariable.Name Vorrang hat)

Re: Prioritäten bei Variablen und Funktionen

1. Juli 2009 11:10

Hallo Natalie,

Natalie hat geschrieben:Habe ich das richtig verstanden? Wenn ja, ergänze ich meinen Einganbsbeitrag um diesen Abschnitt:

Variable vs. Feldname innerhalb WITH
Code:
WITH Recordvariable DO BEGIN
  Name := 'abc';
END;
Gibt es sowohl eine Variable Name als auch Recordvariable.Name, so hat Recordvariable.Name Vorrang.


genau so ist es -- die Recordvariable hat durch das WITH die höchste Priorität.
Genau das ist Sinn und Zweck der WITH-Anweisung.

Gruß
Torsten

Re: Prioritäten bei Variablen und Funktionen

1. Juli 2009 11:11

Sebastian Pfliegel hat geschrieben:Schön ist es auch wenn man eine eindeutige Record-Variable hat aber ein Feld dieses Records hat den gleichen Namen wie eine andere Variable ...
Da braucht man länger bis man herausgefunden hat, warum man einen Compiler-Fehler beim Filtern bekommt. :-|


Hallo Sebastian,
kannst du uns ein Beispiel geben -- irgendwie steh' ich gerade auf dem Schlauch ...

Danke

Re: Prioritäten bei Variablen und Funktionen

1. Juli 2009 11:17

vielleicht weiß ich jetzt, was mit dem Compilerfehler beim Filtern gemeint ist:

Code:
WITH Rec do BEGIN
  SETRANGE(Code, Name);   // Name ist lokale Variable
END;


Dann das neue Feld namens "Name" -- vom Typ vielleicht noch Decimal (blödes Beispiel ...)

Dann wird kompiliert ... Peng!