Der Sinn dieses sinnlosen Programms liegt sinnigerweise darin, dir den Sinn oder Unsinn von Referenzvariablen an einem kurzen aber hinreichend komplexen Beispiel in den Sinn zu rufen.Django90 hat geschrieben:"Was ist der Sinn hinter solch einer Syntax?
Folgende Benutzer bedankten sich beim Autor DeathAndPain für den Beitrag:
Daniel
Code: Alles auswählen.
TYPES: BEGIN OF anydata,
name TYPE string,
data TYPE REF TO data,
END OF anydata.
DATA: partab TYPE TABLE OF anydata.
Das geht auch anders, und sogar mit (noch immer funktionsfähigen) Mitteln aus längst vergangenen Releases. Und zwar kannst Du per (Programmname)Feldname auf Felder aus anderen Programmen zugreifen, insbesondere aus solchen, die in der Aufrufhierarchie weiter oben liegen. Im Funktionsbaustein kannst Du damit aus der Sandbox ausbrechen und Dir aus dem rufenden Programm Informationen beschaffen, die die Kapselung Dir eigentlich nicht rausrücken möchte. Das ist natürlich extrem schmutzig; ich hoffe, Ralf bekommt keinen Herzinfarkt, wenn er das liest.sapnup hat geschrieben:Eine weitere Spielerei mit Referenzen ist, dass man damit z.B. die Input-Einschränkungen von Fubas umgehen kann. Normalerweise wird man ja noch vor dem Compilieren daran gehindert die Werte von Input-Parametern zu ändern. Ist der Input-Parameter jedoch eine Referenz, kann er dereferenziert und der Wert der referenzierten Variable geändert werden. Man ändert damit direkt Wert der (in der Aufrufhierachie weiter oben liegenden) Variable die referenziert- und deren Referenz beim Aufruf an den Fuba übergeben wurde.
Im HCM-Umfeld kenne ich eine, jedenfalls für den lesenden Zugriff auf Werte weiter oben in der Aufrufhierarchie. Und zwar gibt es dort den User Exit ZXPADU02, der von dem Funktionsbaustein EXIT_SAPFP50M_002 gerufen wird. Dieser Exit wird im PAI des Dynpros aufgerufen, das für die Pflege von Personalstammdaten verwendet wird. Über diesen Exit hat man also die Möglichkeit, bei/nach der Pflege von Personalstammdaten noch Konsistenzprüfungen (oder was auch immer) einzubauen, bevor die Daten dann gesichert werden.sapnup hat geschrieben:Eine Anwendung für dieses Szenario fällt mir jetzt jedoch nicht ein.
Code: Alles auswählen.
S = '(MP000000)FCODE'.
ASSIGN (S) TO <FCODE_FROM_MP000000>. " Dieses Feldsymbol enthält jetzt den OK-Code.
Folgende Benutzer bedankten sich beim Autor DeathAndPain für den Beitrag:
sapnup
Ich wäre ein schlechter Entwickler, wenn ich das nicht wüssteDeathAndPain hat geschrieben:Das ist natürlich extrem schmutzig; ich hoffe, Ralf bekommt keinen Herzinfarkt, wenn er das liest.
Oder auch Enhancements.DeathAndPain hat geschrieben:sapnup hat geschrieben:
Sehr nützlich.
(Ehrlicherweise muss man dazusagen, dass die SAP inzwischen auch einen BADI anbietet, den man alternativ zu diesem UserExit nutzen kann.)
ralf.wenzel hat geschrieben:Uiuiui, da wäre ich vorsichtig. In unserem aktuellen Projekt wäre die komplett generische Persistenzschicht ohne Referenzen nur schwerlich denkbar, auch die SAP arbeitet viel damit. Daher sollte man das schon beherrschen.
Ich habe aber auch außerhalb dieser Schicht lauter Prozesse, die für viele Objekte gleich sind (und deshalb nur einmal codiert wurden), das Coding selbst aber erst zur Laufzeit weiß, womit es überhaupt arbeitet. Beispiel: Da wir uns im Arzneimittelbereich bewegen, unterliegt unser Modul der Validierungspflicht. Wir müssen also (vereinfacht gesagt) neben einem Modul für Blutspendedienste eine komplette Simulation eines solchen Blutspendedienstes vorhalten, die alle Prozesse automatisiert testet (weil manuelle Tests im geforderten Umfang kaum zu beherrschen sind). Und die simulierten Objekte sehen natürlich anders aus als die produktiven (weil sie z. B. das Testergebnis persistent speichern müssen), das durchlaufene Coding muss aber produktive sein, weil wir das ja testen müssen.
Wichtig dabei ist eine gute Dokumentation, weil das Coding allein sich nicht mehr selbst erklärt.
Ralf
Nein, tun wir nicht. Ich habe festgestellt, dass die wenigsten etwas mit Worten wie "Mock" anfangen können In der Tat mocken wir, was wir für die Simulation nicht brauchen. Und wenn wir gegen Klassen programmieren würden, könnten wir die kaum austauschen - das geht nur, weil wir gegen Interfaces programmieren.gtoXX hat geschrieben:Da würde ich eher auf ein Konzept mit Dependency Injection, Interfaces und Mocks verweisen. Dann muss nichts separat dokumentiert werden und Generik ist nicht zwingend notwendig. Es klingt für mich so, als codiert ihr gegen Klassen und nicht gegen Interfaces.