XML::Simple in fhem modulen und seiteneffekte

Begonnen von justme1968, 14 November 2014, 23:46:27

Vorheriges Thema - Nächstes Thema

justme1968

inzwischen gibt es je mehrere fhem module die XML::Simple verwenden.

der import kann aber auf unterschiedliche und leider nicht kompatible arten erfolgen. entweder einfach mit use XML::Simple; oder mit use XML::Simple qw(:strict);

ich verwende immer letzteres. die meisten anderen die erste version.

das mehrfache importieren auf unterschiedliche arten führt aber scheinbar dazu das die strict version 'gewinnt' und auch das verhalten in den anderen fhem modulen bestimmt die ohne strict importieren. das führt dann dort zu problemen.

gibt es hierzu eine perl lösung?

wenn nein: sollten wir 'vorschreiben' wie das xml modul importiert werden sollte?

ich könnte mir vorstellen das es solche seiteneffekte auch bei anderen importierten modulen gibt/geben kann. hier würden sich dann die gleichen beiden fragen stellen.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

ntruchsess

Genau dafür gibt es in Perl per package zu deklarierende Namespaces.
In einem FHEM-modul muss nur die Initialized-method in 'main' stehen, alles andere kann (und sollte) sich in einem eigenen package befinden. Siehe z.B. hier im MYSENSORS-modul wie das sauber geht.

- Norbert
while (!asleep()) {sheep++};

rudolfkoenig

Ich habe kein Problem mit Vorschreiben, dazu muesstest du ein Patch fuer contrib/pre-commit erstellen.

Ob dieses Problem mit Norberts Vorschlag geloest wird, weiss ich nicht (kann das jemand bitte testen?), wuerde aber bedeuten, dass die mit use geladenen Module oefters geladen werden, was auch nicht optimal ist.
Will damit nicht sagen, dass man auf package verzichten soll: ein mit Perl-Mechanismen erzeugtes Namespace ist natuerlich sauberer als die von mir bisher praktizierte Prefix-Notation.

ntruchsess

#3
so wie ich das verstanden habe wird das Modul nur einmal geladen (in seinen eigenen Namespace) und dann die gewünschten symbole zur Compilezeit (über die import-methode des packages) in den jeweiligen Namespace des verwendenen packages kopiert. Ich glaube nicht, dass damit mahr als gerade so messbar Speicherplatz verschwendet wird, da werden funktionsreferenzen in den symbol-hash geladen, sonst nichts.
Der parameter 'strict' wird beim Aufruf von import übergeben, damit kann die import-methode entscheiden, was sie wie in den Namespace des verwendenden packages übernimmt.
while (!asleep()) {sheep++};

tupol

#4
Zitat von: ntruchsess am 15 November 2014, 07:14:19
Genau dafür gibt es in Perl per package zu deklarierende Namespaces.
In einem FHEM-modul muss nur die Initialized-method in 'main' stehen, alles andere kann (und sollte) sich in einem eigenen package befinden. Siehe z.B. hier im MYSENSORS-modul wie das sauber geht.

Upps. Ich glaube, da hat sich bisher fast keiner dran gehalten. Ich habe für meine Module jeweils ein existierendes genutzte und dort wird alles im package main als "MODULNAME_Subfunction" deklariert. Ist das jetzt falsch und sollte korrigiert werden? Oder hat die package-Version andere Nachteile?

Gruß

tupol

ntruchsess

es ist nicht grundätzlich falsch (es funktioniert ja). Aber as kann leicht zu unerwarteten Seitenrffekten führen. Best-practice in Perl (ganz unabhängig von fhem) ist jedenfalls packages zu verwenden. Dann ist der eindeutige Bezug auf die Symbole technisch (und nicht nur per Konvention) sichergestellt.
while (!asleep()) {sheep++};

tupol

Zitat von: ntruchsess am 15 November 2014, 10:19:37
es ist nicht grundätzlich falsch (es funktioniert ja). Aber as kann leicht zu unerwarteten Seitenrffekten führen. Best-practice in Perl (ganz unabhängig von fhem) ist jedenfalls packages zu verwenden. Dann ist der eindeutige Bezug auf die Symbole technisch (und nicht nur per Konvention) sichergestellt.

Wenn das "main stream" ist, wäre es möglich, die Konventionen in der Wiki zu beschreiben? Dann könnte ich meine Module auf die Vorgabe umstellen. Der Aufwand ist ja sehr gering.

justme1968

ich habe eben kurz probiert ob es bei dem XML::Simple problem hilft namespaces zu verwenden. und es funktioniert. es reicht im prinzip sogar nur den XML::Simple import selber in einen namespace zu stecken:package myModule;
use XML::Simple qw(:strict);
package main;
das ist natürlich erst mal nur ein workaround um den hier angesprochenen fehler zu vermeiden und ohne das package konzept wirklich für das modul selber zu verwenden.

wie gravierend das öfter laden ist kann ich nicht sagen. ich würde aber eher dahin tendieren zu sagen das die verwendete hardware zu klein ist wenn es nicht möglich ist solche features zu verwenden.

so lange es keine fhem richtlinie für die zu verwenden package namen gibt ist die notwendige eindeutigkeit der namen aber nur auf eine andere ebene von konvention geschoben. 
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968