Seite 2 von 2

Re: Was, zum Henker, soll hieran falsch sein ?

Verfasst: 1. Jun 2022 21:38
von guinnes
udo1toni hat geschrieben: 1. Jun 2022 20:10 Das Problem ist ziemlich sicher, dass die Variablen und Konstanten nicht typisiert sind. +
Hab ich jetzt gemacht, ändert an den Rules 3 und 5 nichts. Das sind die Rules mit Funktion, die die globalen Konstanten benutzen
Der Code ist (das wirst Du sicher selbst erkennen) fürchterlich.
Natürlich ist der Code fürchterlich, ich wollte damit auch keinen Schönheitspreis gewinnen ;) , sondern das Problem so kurz wie möglich darstellen
Funktionen sind in der DSL nicht gut unterstützt, und ja, man kann Lambdas dazu missbrauchen, muss dann aber damit leben, dass oftmals sehr seltsame Dinge passieren.
Es sind mit in letzten 2 Jahren einige Dinge aufgefallen, die seltsam sind, aber nicht so was gravierndes.
Da kriege ich z.B. die Meldung "Assignment to final variable" es tut aber trotzdem oder
ich kriege im MSCode den Fehler "Cannot refer to the non-final variable wAVGCount inside a lambda expression" und tut ebenfalls
Die Timer Variable ist beispielsweise global definiert, und Timer funktionieren absolut zuverlässig (im möglichen Rahmen, d.h. die *.rules Datei darf nicht zwischendrin neu geladen werden und bevor die Timer Variable mit einem Timer gefüllt wird (bzw. mit dem Zeiger auf den Scheduler Eintrag) muss ein evtl. vorhandener Timer immer gecancelt werden, also so:

Code: Alles auswählen

//vor der ersten Rule
var Timer tMyTimer = null // Initialisierung wenn die Datei neu geladen wird

rule " meine Timer Rule"
when
   Item Blah received command
then
    tMyTimer?.cancel  // Falls ein Timer läuft bbrechen
    if(receivedCommand==ON)
        tMyTimer = createTimer(now.plusSeconde(1),[|
            // tu was
            tMyTimer = null
        ])
end
Bist du dir sicher, daß "tMyTimer.cancel" auch geht, wenn der Timer null ist ?
Der Timer wird nach dem Ablauf ( nach einer Sekunde ) sowieso auf null gesetzt.
In der Fehlermeldung siehst Du ja, dass er immer versucht, float mit double zu multiplizieren, da bin ich mir ziemlich sicher, dass das nicht automatisch geht.
jetzt nicht mehr. Logfile :

Code: Alles auswählen

2022-06-01 20:52:00.065 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Demo Inc 5': Could not invoke method: org.eclipse.xtext.xbase.lib.FloatExtensions.operator_multiply(float,double) on instance: null
2022-06-01 20:53:00.005 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'Demo Inc 3': Could not invoke method: org.eclipse.xtext.xbase.lib.FloatExtensions.operator_plus(float,float) on instance: null
Fazit :
Es gibt den Fehler wenn
1. Die Konstanten nicht typisert sind bzw. die Typen nicht identisch sind ( was ja eher Java-untypisch ist ) und
2. eine Funktion auf die Konstanten zugreift

Re: Was, zum Henker, soll hieran falsch sein ?

Verfasst: 2. Jun 2022 08:29
von udo1toni
guinnes hat geschrieben: 1. Jun 2022 21:38 Bist du dir sicher, daß "tMyTimer.cancel" auch geht, wenn der Timer null ist ?
Obacht! Das ist nicht der Befehl, den ich verwende :) Das Fragezeichen gehört da hin und hat eine Bedeutung.

Code: Alles auswählen

tMyTimer?.cancel
ist gleichbedeutend mit

Code: Alles auswählen

if(tMyTimer !== null)tMyTimer.cancel
und auch das !== hat eine Bedeutung ;)
guinnes hat geschrieben: 1. Jun 2022 21:38 Es gibt den Fehler wenn
1. Die Konstanten nicht typisert sind bzw. die Typen nicht identisch sind ( was ja eher Java-untypisch ist ) und
2. eine Funktion auf die Konstanten zugreift
Die fehlende Typisierung ist nicht zwingend problematisch, sie kann aber zum Problem werden. Die Lambdas sind ja keine "echten" Funktionen, und wie gesagt, es gibt da seltsame Effekte. Dass die Variablen nicht vererbt werden, ist offensichtlich so eine Seltsamkeit.

Innerhalb einer Rule funktioniert das aber problemlos.

Die Fehlermeldung
guinnes hat geschrieben: 1. Jun 2022 21:38 "Assignment to final variable"
sagt es ja schon. Die Variable ist final, eine Zuweisung ist eigentlich nicht zulässig.
guinnes hat geschrieben: 1. Jun 2022 21:38 "Cannot refer to the non-final variable wAVGCount inside a lambda expression"
Weist ja auch nur darauf hin, dass die nicht-finale Variable innerhalb des Lambdas in den Augen des Präprozessors (oder welcher Teil da Alarm schlägt) ungültig ist und deshalb nicht referenziert werden kann. Das gilt aber nur, wenn das Lambda unabhängig vom übergeordneten Kontext ist, also z.B. das Lambda eines Timers, denn der Timer läuft erst, wenn die Rule nicht mehr läuft.
Wenn der Zugriff auf die Variabale dann trotzdem funktioniert, ist das ein Fehler im Speichermanagement, bzw. Glück, weil die Garbage Collection noch nicht aufgeräumt hat. (Und aber immer noch ein Fehler, weil der Zugriff eigentlich aktiv verhindert werden müsste, streng genommen ist das sogar ein schwerer Fehler der gefixt werden müsste.