FHEM Forum

FHEM - Entwicklung => FHEM Development => Perl Ecke => Thema gestartet von: RichardCZ am 25 März 2020, 18:02:27

Titel: PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 25 März 2020, 18:02:27
PBP führt das auf zweieinhalb Seiten 194-196 aus.

Ganz wichitg ist, dass diese Regel (verwende keine Prototypes) auch nicht alleine für sich steht.
Bevor man also soweit ist, dass man die ganzen Puzzlestücke (PBP Regeln) in ihrer Gesamtheit Überblickt, gibt es nur zwei Dinge die helfen: Geduld & Vertrauen.

Aber ich versuche mal einige FHEM-spezifischen Beispiele und Erläuterungen im Kontext loszuwerden:

CoolTux hat ja - weil er durch einige PMs mit mir ein wenig Vorsprung hat - die Protos in 73_AutoShuttersControl rausgenommen:
https://svn.fhem.de/trac/changeset?reponame=&new=21506%40trunk%2Ffhem%2FFHEM%2F73_AutoShuttersControl.pm&old=21495%40trunk%2Ffhem%2FFHEM%2F73_AutoShuttersControl.pm

Von all den Änderungen würde ich gerne eure Aufmerksamkeit auf "sub Set" richten. Was sehen wir in der vorhergehenden Version?

https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/73_AutoShuttersControl.pm?rev=21495#L592

sub Set($$@) {
    my ( $hash, $name, @aa ) = @_;
    my ( $cmd, @args ) = @aa;
...


Angeblich nimmt Set ja zwei Skalare und eine Liste. Tja...
In Wirklichkeit nimmt Set drei Skalare und eine Liste, nur hat man das dritte Skalar in der Liste versteckt.
Man erzeugt also eine Illusion - nicht mehr und nicht weniger - einer formalen Definition der Übergabeparameter.

Aber das ist nur ein Nebenschauplatz. In Wirklichkeit gibt es eine wesentlich bessere Methode Parameter zu übergeben (named Arguments - siehe PBP 182/183) sobald man vielleicht mal mehr als 3 Parameter hat. Und warum sollte man einen PVC Spoiler an einen rostigen Golf pappen, wenn man einen GTR haben kann?

Also: Prototypes sind schlecht und man kann die fast immer wegschmeissen. (*)
Geduld & Vertrauen: Es werden wesentlich bessere Methoden der Parameterübergabe und Validierung vorgestellt werden, so dass niemand Prototypes nachtrauern muss.






(*) Vorsicht ist geboten, wenn irgendwo z.B. ein sub blah(\@\@) steht. Aber das scheint nicht Usus zu sein. Falls jemand dem irgendwo begegnet, frage man mich wie man das rausoperiert.

Titel: PBP: Warum sind Prototypen schlecht?
Beitrag von: justme1968 am 25 März 2020, 20:58:15
ZitatAngeblich nimmt Set ja zwei Skalare und eine Liste. Tja...
nein...

es sind zwei skalare und eine liste. das die liste danach noch mal zerlegt wird ändert nichts daran.

ZitatMan erzeugt also eine Illusion - nicht mehr und nicht weniger - einer formalen Definition der Übergabeparameter.
ja. eine hilfe um auf einen blick an bestimmte information zu kommen. wenn der hingeschriebene prototyp nicht um beabsichtigten code passt ist das genau so schlecht wie ein falscher kommentar oder ein falsch benannter parameter. der prototyp verhindert bestimmte fehler. nicht alle. nicht optimal. aber manche. und er kostet nichts.

das benannte argumente einer ellenlangen liste an unbenannten parametern vorzuziehen ist ist klar, aber das hat nichts mit protypen zu tun. das eine verbessert die lesbarkeit (und fehleranfälligkeit) an der aufrufenden stelle. an der aufgerufenen stelle sieht man erst mal nichts davon.


der set und get fall ist im übrigen ein schlechtes weispiel weil im array nur die einzelnen durch leerzeichen getrennten token einer kommando eingabe stecken und man name auch noch dazu zählen könnte. der Prototyp sollte also eigentlich ($@) heissen und die verarbeitung der liste sollte man parseParams überlassen die einem dann genau den hash mit benannten parametern und einem array für den rest zurück gibt.

und wenn man im modul hash parseParams gesetzt hat passiert das sogar komplett automatisch und die Set routine wird genau damit aufgerufen.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 25 März 2020, 21:42:32
Zitat von: justme1968 am 25 März 2020, 20:58:15
der prototyp verhindert bestimmte fehler. nicht alle. nicht optimal. aber manche. und er kostet nichts.

Prototypen verursachen Fehler. Da es natürlich Du warst, der PBP für dogmatisches Teufelswerk hält, vermute ich, dass Du da nicht mehr als 2-3 Seiten gelesen hast.

Das Beispiel auf Seite 194 zeigt ziemlich deutlich welche Probleme entstehen, wenn man mit Prototypen implizites Verhalten einführt, wie z.B.

sub swap_arrays (\@\@) { ...

und dann später

swap_arrays(@sheep, @goats);

Jeder normal denkende Perl Entwickler wird sich beim Aufruf sagen, dass hier die zwei Listen zu einer geplättet werden. Protos machen es unmöglich auf das Verhalten einer Routine zu schliessen indem man sich ihren Aufruf im Programmcode anschaut. Falls man die Sache ernst nimmt, müsste man sich eigentlich IMMER die Definition ansehen.

Ich habe mir sogar die Mühe eines grep und tamtam gemacht und siehe da, es gibt doch 2-3 echt problematische Stellen im FHEM code:

FHEM/98_Modbus.pm:sub Modbus_CheckEval($\@$$);
FHEM/00_SIGNALduino.pm:sub SIGNALduino_MatchSignalPattern($\@\%\@$){
FHEM/00_SIGNALduino.pm:sub SIGNALduino_padbits(\@$) {
FHEM/95_YAAHM.pm:    $res .= "sub HouseTimeHelper(\@){\n".


Da kann man die Protos nicht einfach so entfernen. In den allermeisten anderen Fällen kann und sollte man.

Prototypen haben noch nicht einmal den Nutzen um im Fall von sub-Referenzen ... naja ... von Nutzen zu sein.

Zitatprototypes have no influence on subroutine references like \&foo or on indirect subroutine calls like &{$subref} or $subref->() .

Prototypen sind primär dazu gedacht, damit man subs definieren kann die sich wie builtins verhalten. Sagt nicht PBP, sagt die Perl Doku
https://perldoc.perl.org/perlsub.html#Prototypes

Zitatthe intent of this feature is primarily to let you define subroutines that work like built-in functions

Wenn man ganz hart ist, kann man mit Prototypen Neue Syntax in Perl einführen. Aber bitte ... in FHEM?
Diesen Anwendungsfall gibt es in FHEM einfach nicht. Ergo, werden hier die Prototypen einfach nur falsch angewendet/misbraucht.
Aber wie gesagt: Ich werde jetzt nicht das Buch rezitieren


Zitat
der set und get fall ist im übrigen ein schlechtes weispiel weil im array nur die einzelnen durch leerzeichen getrennten token einer kommando eingabe stecken und man name auch noch dazu zählen könnte. der Prototyp sollte also eigentlich ($@) heissen

Nein, der Prototyp sollte gar nichts heißen, der sollte einfach nicht da sein. Alleine schon die Tatsache, dass es für die Semantik komplett Wurst ist, ob in dem Set Fall $$@, $$$@ oder gar nix steht zeigt, dass "gar nix" die beste Alternative ist.


Zitat
und die verarbeitung der liste sollte man parseParams überlassen die einem dann genau den hash mit benannten parametern und einem array für den rest zurück gibt.

und wenn man im modul hash parseParams gesetzt hat passiert das sogar komplett automatisch und die Set routine wird genau damit aufgerufen.

Ich vermute, Du meinst

parseParams($;$$$) aus fhem.pl, nicht das fast baugleiche
parseParams($;$$$$) aus 00_MQTT

Die Verwendung von zentralen Funktionen wie parseParams anstelle irgendwelcher selbstgestrickten parsing Geschichten ist wieder ein anderes Thema und prinzipiell richtig. Sobald sich parseParams auch wäscht und die Zähne putzt, werde ich das sogar mit Nachdruck empfehlen.


Hinsichtlich Prototypes bleibt es dabei: Ist die Pest, macht es weg. Diejenigen, die neue Perl Syntax, neue Befehle etc. damit generieren wollen fühlen sich ja nicht angesprochen.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: CoolTux am 25 März 2020, 21:53:43
Zitat von: justme1968 am 25 März 2020, 20:58:15
der set und get fall ist im übrigen ein schlechtes weispiel weil im array nur die einzelnen durch leerzeichen getrennten token einer kommando eingabe stecken und man name auch noch dazu zählen könnte. der Prototyp sollte also eigentlich ($@) heissen und die verarbeitung der liste sollte man parseParams überlassen die einem dann genau den hash mit benannten parametern und einem array für den rest zurück gibt.

und wenn man im modul hash parseParams gesetzt hat passiert das sogar komplett automatisch und die Set routine wird genau damit aufgerufen.

Hallo Andre,

Hättest Du ein Beispielmodul für mich für genau diese automatisierte Verarbeitung. Ich würde das gerne nehmen.


Grüße
Marko
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: justme1968 am 25 März 2020, 21:59:46
wenn du im modul hash parseParams setzt wird deine SetFn nicht mehr mit der string liste sondern mit dem ergebnis von parseParams aufgerufen.

siehe  DevelopmentModuleIntro seite im wiki
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: CoolTux am 25 März 2020, 22:01:05
Zitat von: justme1968 am 25 März 2020, 21:59:46
wenn du im modul hash parseParams setzt wird deine SetFn nicht mehr mit der string liste sondern mit dem ergebnis von parseParams aufgerufen.

siehe  DevelopmentModuleIntro seite im wiki

Das schaue ich mir mal morgen an.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 25 März 2020, 23:15:37
Zitat von: RichardCZ am 25 März 2020, 21:42:32
Die Verwendung von zentralen Funktionen wie parseParams anstelle irgendwelcher selbstgestrickten parsing Geschichten ist wieder ein anderes Thema und prinzipiell richtig. Sobald sich parseParams auch wäscht und die Zähne putzt, werde ich das sogar mit Nachdruck empfehlen.

https://gl.petatech.eu/root/HomeBot/-/commit/7aa4faaaf84ec090ef5f9f3b10d6876d39e89f22

ist aber noch nicht ganz fertig (und vor allem ungestestet). Für heute mach ich lieber Feierabend.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: justme1968 am 26 März 2020, 08:35:29
zurück zum thema prototypen:

die beiden beispiele die im buch verwendet werden um prototypen als generell schlecht darzustellen zeigen nur eins: das sich die semantik ändern wenn man protypen willenlos einführt. das heisst im übrigen auch das sich diese beim grundlosen entfernen der prototypen ebenfalls ändern. das ist eine zusätzliche potentielle fehlerquelle.

sie zeigen nicht das das die verwendung von protypen um den code intent klarer zu machen schlecht oder falsch ist. sie sagen nichts darüber aus wie es mit code ausschaut der direkt mit verwendung von protypen entstanden ist. das in beiden beispielen listen vorkommen zeigt nur das es mit protypen und listen probleme geben kann wenn man nicht weiss was man tut. sie sagen nicht das es nicht auch andere fälle gibt. das die beispiele die verwendet werden extra so gestrickt sind das der code 'zufällig' schon mehr kann und im table lookup fall auch funktioniert ist ein schlechter taschenspieler trick. wenn die implementierung damit nicht klar kommen würde wäre das ergebnis des falschen aufrufs schlicht und einfach ein fehler.


prototypen sind teil des designs. sie führen nicht implizites verhalten ein sondern machen das verhalten explizit. sie erlauben auf einen ersten kurzen blick einen einblick in die idee hinter einer routine. sie ermöglichen eine gewisse art von fehler frühzeitig zu erkennen. nicht immer. aber eben auch nicht niemals.

ein min($$) macht ganz klar das diese routine für genau zwei parameter bestimmt ist. ein min(@) hingegen ist für beliebig viele paramter. ein falscher aufruf (3 statt 2 parameter) von min kann frühzeitig erkannt werden. eine version ohne protypen gibt ohne genaues anschauen des quelltextes keinerlei information darüber ob ein aufruf mit drei parametern gültig ist. wenn man sich bei der implementierung nichts weiter gedacht hat liefert er einfach falsche ergebnisse ohne fehlzuschlagen.

bei eine änderung der routine von nur zwei auf mehr parameter mit anpassen des protypen zeigt das der aufruf kompatibel geblieben ist. bei einem potentiellen umbau von beliebig vielen (wer braucht das schon) auf nur drei parameter würde der falsche aufruf erkannt.

das nur bestimmte probleme damit erkannt werden ist unbenommen. das heisst aber nicht das man deshalb auf alle möglichkeiten verzichten sollte.

es kommt sie immer darauf an das man weiss was man tut.

es gibt in fhem ganz sicher viele dinge die man anders oder sogar besser machen kann. es gibt echte fehler die man beheben kann. es gibt von architektur über dokumentation und optimierung bis hin zu code reviews möglichkeiten sich einzubringen und beizutragen. ganz zu schweigen vom schreiben neuer module. das entfernen der protypen gehört ganz sicher nicht dazu. 

ps: der ganze sinn und zweck von parseParams ist das parsen einer kommandozeile in einen ergebnis hash und array. die beiden variablen h und a zu nennen ist bei weitem nicht das schlechteste. x und y wäre schlechter. hash und array oder result_hash und result_array wären länger aber nicht besser.

pps: wenn ein grosser teil der änderungen an einer funktionierenden routine daraus besteht kommentarlos einen anderen stil zu verwenden (aufrufe mit/ohne klammern, ?: statt if, ...) ist das oft keine frage von besser sondern nur von anders.

ppps: die umstellung mit verwendung des defined-or finde ich schön. lustigerweise war dessen erste verwendung in fhem damals auch das erste problem das jemand anders mit einem meiner module hatte. den gibt es nämlich erst ab perl 5.10 und zumindest damals waren noch viele ältere perl versionen in verwendung.

Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: justme1968 am 26 März 2020, 08:46:43
in deiner umgebauten parseParams ist in zeile 5839 noch ein ; zu viel.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: justme1968 am 26 März 2020, 08:56:17
das verhalten ist auch noch nicht mit der alten version identisch:

parsen von 'set name test1 test2=abc test3 "test4 test4" test5="test5 test5" test6=\'test6=test6\' test7= test8="\'" test9=\'"\' {my $x = "abc"} test10={ { my $abc ="xyz" } }'

sollte das hier geben:$VAR1 = [
          'set',
          'name',
          'test1',
          'test3',
          'test4 test4',
          '{my $x = "abc"}'
        ];
$VAR2 = {
          'test9' => '"',
          'test5' => 'test5 test5',
          'test6' => 'test6=test6',
          'test2' => 'abc',
          'test8' => '\'',
          'test7' => '',
          'test10' => '{ { my $abc ="xyz" } }'
        };

aktuell gibt es aber das hier: $VAR1 = [
          'set',
          'name',
          'test1',
          'test3',
          'test4 test4',
          '{my $x = "abc"} test10={ { my $abc ="xyz" } }'
        ];
$VAR2 = {
          'test6' => 'test6=test6',
          'test5' => 'test5 test5',
          'test7' => '',
          'test2' => 'abc',
          'test9' => '"',
          'test8' => '\''
        };


d.h. die unterschieldliche behandlung von test10

ohne genau geschaut zu haben vermute ich es liegt am geänderten zusammenfassen und zählen der geklammerten teile. du zählst alles auf einen schlag, korrekt ist aber nur bis zur gleichen klammer ebene herunter zu zählen.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 26 März 2020, 08:59:00
Zitat von: justme1968 am 26 März 2020, 08:35:29
prototypen sind teil des designs. sie führen nicht implizites verhalten ein sondern machen das verhalten explizit. sie erlauben auf einen ersten kurzen blick einen einblick in die idee hinter einer routine.

Wie bereits erwähnt, steht die Empfehlung Prototypen zu knicken nicht alleine für sich da, sie ist Teil eines umfassenden Regelwerks (Habitual concepts) und fügt sich in dieses ein.

Das Argument, Prototypen erlauben "durch einen einfachen Blick darauf" eine wie auch immer geartete Analyse bzw. Erkenntnis des Codes dahinter halte ich für einen billigen Taschenspielertrick.

Für gewöhnlich macht so etwas die Dokumentation. Nur weil man diese nicht hat, ebenso wie man tests nicht hat, ebenso wie man keine klare Struktur bei parametervalidierungen hat bedeutet das noch lange nicht, dass man durch die missbräuchliche Art und Weise - also wozu man glaubt Prototypen zu verwenden - all diese Defizite auf magische Art und Weise behebt.

Du klammerst Dich hier an eine Fata Morgana.

Zitat
das nur bestimmte probleme damit erkannt werden ist unbenommen. das heisst aber nicht das man deshalb auf alle möglichkeiten verzichten sollte.

Es gibt bessere Möglichkeiten. Nochmal: Warum soll ich einen gammligen PVS Spoiler auf einen rostigen Golf pappen wenn ich einen GTR haben kann?

Zitat
es kommt sie immer darauf an das man weiss was man tut.
...
das entfernen der protypen gehört ganz sicher nicht dazu. 

Das sowieso (wissen was man tut). Und das Entfernen sinnloser Cargo Cult Konzepte gehört in erster Linie dazu.

Zitat
ps: der ganze sinn und zweck von parseParams ist das parsen einer kommandozeile in einen ergebnis hash und array. die beiden variablen h und a zu nennen ist bei weitem nicht das schlechteste. x und y wäre schlechter. hash und array oder result_hash und result_array wären länger aber nicht besser.

Eine Variable @a zu nennen ist extrem schlecht. Wer das tut, hat weder die Empfehlung verstanden, man solle im gleichen Scope nicht gleiche Variablennamen verwenden für verschiedene Typen (also z.B. nicht @param, %param und $param im gleichen Scope)

Wenn man das weiß und auch weiß, dass $a und $b spezielle globale Variablen sind, macht man diesen Unsinn nicht. Schon gar nicht verteidigt man ihn.

Zitat
pps: wenn ein grosser teil der änderungen an einer funktionierenden routine daraus besteht kommentarlos einen anderen stil zu verwenden (aufrufe mit/ohne klammern, ?: statt if, ...) ist das oft keine frage von besser sondern nur von anders.

Da müsste man natürlich auch informiert sein und wissen warum bei BUILTINS (nicht Funktionen) die Argumente bevorzugt nicht mit Klammern angegeben werden.

Man kann sich natürlich spreizen und erstmal "dagegen sein". Kein Problem. Man könnte sich auch ein wenig kooperativ zeigen und von Synergien profitieren. So würde es mir z.B. helfen, wenn Du eine gute represäntative Liste der typischen Argumente an parseParams liefern würdest. Dann könnte ich eine Testsuite und einen Benchmark schreiben.

Ich hielte sowas für sinvoller als Kreuzzüge.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: justme1968 am 26 März 2020, 09:02:04
ZitatSo würde es mir z.B. helfen, wenn Du eine gute represäntative Liste der typischen Argumente an parseParams liefern würdest. Dann könnte ich eine Testsuite und einen Benchmark schreiben.

s.o. :)
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 26 März 2020, 09:04:46
Zitat von: justme1968 am 26 März 2020, 08:56:17
das verhalten ist auch noch nicht mit der alten version identisch:

Ich schrieb ja gestern um 23Uhr-irgendwas es sei noc hnicht fertig und nicht getestet.
Habe dann abends aber noch einen fix geliefert.

https://gl.petatech.eu/root/HomeBot/-/commit/335a787de26daf172779ae370c4093694ff4cf33

$ tr_count.pl
$VAR1 = [
          'set',
          'name',
          'test1',
          'test3',
          'test4 test4',
          '{my $x = "abc"}'
        ];
$VAR2 = {
          'test9' => '"',
          'test8' => '\'',
          'test5' => 'test5 test5',
          'test10' => '{ { my $abc ="xyz" } }',
          'test2' => 'abc',
          'test7' => '',
          'test6' => 'test6=test6'
        };

Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: justme1968 am 26 März 2020, 09:16:50
ZitatDa müsste man natürlich auch informiert sein und wissen warum bei BUILTINS (nicht Funktionen) die Argumente bevorzugt nicht mit Klammern angegeben werden.

deshalb steht da oben ja auch: kommentarlos...

ich sehe nirgendwo eine information oder erklährung
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 26 März 2020, 09:25:35
Zitat von: justme1968 am 26 März 2020, 09:02:04
s.o. :)

Bischen spät aber besser als nix. Mehr davon (Grenzfälle etc.). Hinsichtlich dieses Testfalls verhalten sich die Subs nun gleich

sub pP_mud_puddle {
    parseParams($test);
}

sub pP_pixie_dust {
    parseParams2($test);
}

timethese(100000, {
                  'pP1'  => \&pP_mud_puddle,
                  'pP2'  => \&pP_pixie_dust,
                 });


Benchmark: timing 100000 iterations of pP1, pP2...
       pP1:  6 wallclock secs ( 5.70 usr +  0.00 sys =  5.70 CPU) @ 17543.86/s (n=100000)
       pP2:  5 wallclock secs ( 5.16 usr +  0.00 sys =  5.16 CPU) @ 19379.84/s (n=100000)


Die neue ist so 10% schneller - und kürzer und übersichtlicher und immer noch nicht fertig. Noch eine Mannwoche Arbeit und man kann die vielleicht zur Verwendung empfehlen.  ;)
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 26 März 2020, 09:27:23
Zitat von: justme1968 am 26 März 2020, 09:16:50
deshalb steht da oben ja auch: kommentarlos...

ich sehe nirgendwo eine information oder erklährung

siehe PBP Seite 13/14

aber ist bestimmt wieder nur ein billiger Taschenspielertrick.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: SCMP77 am 26 März 2020, 10:31:03
Zitat von: RichardCZ am 26 März 2020, 08:59:00Das Argument, Prototypen erlauben "durch einen einfachen Blick darauf" eine wie auch immer geartete Analyse bzw. Erkenntnis des Codes dahinter halte ich für einen billigen Taschenspielertrick.

Jein. Bei der ganzen Diskussion sollte man nicht vergessen, dass Perl schon zur Kompilierzeit dort anhand dieser Prototypen gewisse Checks macht. Schafft man die Prototypen ganz ab, werden solche Fehler erst zur Laufzeit erkannt.

Bei FHEM ist das leider aktuelle so, dass solche Fehler meist bewirken, dass das ganze System steht. Kompilierfehler führen dazu, dass das Modul erst gar nicht eingebunden wird und so das System nicht blockiert. Ich bin daher sehr skeptisch, Prototypen ganz weg zu lassen. Ein "Taschenspielertrick" ist aus meiner Sicht nicht. Sicher, es gibt auch tausend andere Möglichkeiten, durch Modulfehler FHEM zum stehen zu bekommen, weil alles seriell abgearbeitet wird, insofern finder man so nur relativ wenig Fehler durch den Kompiler selber, aber die Frage wäre, ist es wirklich notwendig auf diese zu verzichten?
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 26 März 2020, 11:00:54
Zitat von: SCMP77 am 26 März 2020, 10:31:03
Jein. Bei der ganzen Diskussion sollte man nicht vergessen, dass Perl schon zur Kompilierzeit dort anhand dieser Prototypen gewisse Checks macht. Schafft man die Prototypen ganz ab, werden solche Fehler erst zur Laufzeit erkannt.

<loriot>
ach?
</loriot>

Bleiben wir doch bei parseParams

sub
parseParams($;$$$)


Bitte welche "gewissen Checks" werden da gemacht?

Der hier? parseParams(\{})

$VAR1 = [
          'REF(0x557396b73948)'
        ];
$VAR2 = {};


Der? parseParams([]) Der? parseParams(\[]) oder der? parseParams([],\{},'blah', *FH);

Wacht auf Leute - all das und noch viel mehr akzeptiert die gegenwärtige parseParams Deklaration mit ihren Protos anstandslos (Compile & Laufzeit). Haben alle eure Fata Morganas Türgriffe oder wie schafft Ihr es euch so beharrlich daran festzuklammern?

Ich bin natürlich gemein. ($;$$$) ist nämlich genau so ein Feigenblatt wie (.*) in regulären Ausdrücken und macht es einfach dieses Konzept "vorzuführen".

Zitat
Kompilierfehler führen dazu, dass das Modul erst gar nicht eingebunden wird und so das System nicht blockiert.

Da sollte normalerweise eigentlich schon ein pre-commit hook im Subversion eingreifen, so dass ein Modul mit Kompilierfehlern gar nicht erst ins Repo käme. Andere Baustelle.

Zitat
Ich bin daher sehr skeptisch, Prototypen ganz weg zu lassen. Ein "Taschenspielertrick" ist aus meiner Sicht nicht.

Ich gehe davon aus, ihn oben explizit aufgedeckt zu haben.

Zitat
Sicher, es gibt auch tausend andere Möglichkeiten, durch Modulfehler FHEM zum stehen zu bekommen, weil alles seriell abgearbeitet wird, insofern finder man so nur relativ wenig Fehler durch den Kompiler selber, aber die Frage wäre, ist es wirklich notwendig auf diese zu verzichten?

Meine Absicht ist es, den FHEM Code so 100x robuster zu bekommen als er jetzt ist. Das für sich genommen ist schon eine Herkulesaufgabe, selbst wenn alle am gleichen Strick ziehen (und nicht diesen anderen drehen). Stattdessen muss ich hier "rechtfertigen", warum man nicht versuchen sollte einen kaputten Auspuff mit Tesa und Papiertaschentüchern zu reparieren. Das schlaucht.

Aber nein, keiner muss auf seine geliebten Protos verzichten. Wer mag, darf sie behalten. Ich empfehle halt die zu entfernen, werde das für mich und meinen Code machen.

Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: CoolTux am 26 März 2020, 12:25:04
Zitat von: justme1968 am 25 März 2020, 21:59:46
wenn du im modul hash parseParams setzt wird deine SetFn nicht mehr mit der string liste sondern mit dem ergebnis von parseParams aufgerufen.

siehe  DevelopmentModuleIntro seite im wiki

Vielen Dank Andre. Ich habe ASC auf parseParams umgebaut und es klappt super.


Grüße
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: justme1968 am 27 März 2020, 11:42:50
zu den klammern für buildins:

die regel sagt: 'nicht tun', die begründung gibt (wie vermutet) keinen technischen grund sondern ein 'ich finde es übersichtlicher' also lass sie weg. ausser wenn sie doch nötig sind.

das ist genau die art von argumenten die komplett sinnlos sind wenn man a) etwas anderes übersichtlicher findet und/oder b) auf konsistenz wert legt und/oder c) sich an existierenden code anlehnt um kein durcheinander zu schaffen.

sich darüber zu streiten welcher stil der richtige ist ist genau das was wir nicht brauchen um fhem besser zu machen.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 27 März 2020, 12:07:12
Zitat von: justme1968 am 27 März 2020, 11:42:50
sich darüber zu streiten welcher stil der richtige ist ist genau das was wir nicht brauchen um fhem besser zu machen.

Die Welt ist größer. Immer.

Es geht hier nicht um Dich, oder um mich. Es geht auch nicht um FHEM alleine.

Ich finde es schon nett, wenn ich einen 5,6,7 Jahre alten Code von jemandem sehe, wo ich mich inhärent zurechtfinde, weil er so


$attr{$name}{unit_windspeed}      //= "km/h";
$attr{$name}{unit_solarradiation} //= "lux";
$attr{$name}{round}               //= 4;


und nicht so

    $attr{$name}{unit_windspeed} = "km/h"
      if ( !defined( $attr{$name}{unit_windspeed} ) );
    $attr{$name}{unit_solarradiation} = "lux"
      if ( !defined( $attr{$name}{unit_solarradiation} ) );
    $attr{$name}{round} = 4 if ( !defined( $attr{$name}{round} ) );


aussieht. Ich finde es schon toll, wenn ich auf perl.org, blogs.perl org einen Code von Leuten sehe, die sich an PBP halten, weil - ob Du es glaubst oder nicht - das ist nunmal Standard "da draussen" und ich mich gleich zurechtfinde.

Oder wenn ich die Synopsis moderner Module lese und die auch nicht aussieht wie Kraut und Rüben. Und ja, der FHEM code sieht in weiten Teilen wie Kraut und Rüben aus. Mein parseParams ist schon jetzt wesentlich besser als das Originale, weil ich einige PBP Prinzipien angewendet habe.

Wenn Du das nicht einsiehst und sagst "Geschmacksfrage". ¯\_(ツ)_/¯ Dann lügt sich einer von uns in die Tasche.

Ich schreibe heutzutage besseren Perl Code dank PBP und dank der "Habits" die ich mir wegen PBP angeeignet habe. Genauso wie viele meiner Kollegen und es ist eine WOHLTAT, Code von jemand Fremden in die Hand zu bekommen und sich darin so zurechtzufinden als sei es der eigene.

Wenn man alleine in seiner Hütte sitzt und individuellen autodidaktischen Perl Code zusammenstöpselt, dann ist das ja ok, aber die Welt ist eben größer als die eigene Hütte. Immer.

Und es kommt halt nicht gut, wenn Du z.B. in Deutschland mal mit Deinem Auto aus der Hütte rausfährst und erstmal in der linken Spur fährst, die Verkehrszeichen missachtest und Fernlicht als Blinker und Blinker als Fernlicht benutzt.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: rudolfkoenig am 27 März 2020, 12:15:07
Wenn man diese Argumentation akzeptiert, und sie konsequent anwendet, muss man jegliche Vielfalt (wofuer Perl mAn steht) unterdruecken.
Ich bin dagegen.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: justme1968 am 27 März 2020, 12:15:47
auch wenn völlig klar ist welche der beiden lesbarer ist haben diese beiden beispiele absolut nichts mit der klamer verwendung für buildins zu tun. also thema verfehlt.

wenn du 5-7 jahre alten code besser verstehst wenn er gerade zufällig die regeln einhält die dir genehm sind ist das schön. gilt aber in der verallgemeinerung nicht für alle. andere verwenden aus genau so gutem grund andere regeln und freuen sich wenn sie diese wieder finden.

ja. genau. 'da draussen' ist größer als es deine pbp welt zulässt.

der stvo vergleich hinkt leider. es gibt genau eine stvo. die jeder einzuhalten hat. aber mehr als eine art klammern zu setzen oder seinen code zu formatieren. alle mit genau so guten begründungen. auch wenn es dir nicht passt.

bleib lieber bei deinem bibel vergleich. der passt besser. auch wenn es schade ist das die vielen zufälligen regeln den blick auf die übrigen sinnvollen und begründbaren verstellen.

Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 27 März 2020, 12:27:39
Zitat von: rudolfkoenig am 27 März 2020, 12:15:07
Wenn man diese Argumentation akzeptiert, und sie konsequent anwendet, muss man jegliche Vielfalt (wofuer Perl mAn steht) unterdruecken.
Ich bin dagegen.

Das wofür Perl steht weiß ich und der PBP Autor sehr gut. Ich möchte zitieren:

"there's more than one way to do it" (TMTOWTDI) ausgesprochen: "Tim Toady"

Ja, dafür steht Perl.

Aber das heißt noch lange nicht - dass alle diese Wege gleich gut sind.

PBP bedeutet auch nicht, dass man ein Korsett vorgesetzt bekommt, das es einem unmöglich macht irgendwelche Freiheitsgrade auszunutzen.
Und nochmal: Nix von alldem hier ist Pflicht, wer Kraut und Rüben möchte, soll Kraut und Rüben haben.

Allerdings ist dies aus operativer Sicht extrem kurzsichtig. Dir ist doch wichtig, dass Module nicht verwaisen. Mir auch.
Ein PBP-konformes Modul ist für den Modulautor wesentlich einfacher als irgendein individuelles Kraut/Rüben Feld.

Warum?

Bei Problemen mit dem Code findet er einfacher Hilfe, weil es für potentielle Helfer einfacher ist "durchzusteigen" durch den Code.
Wenn er irgendwann nicht mehr Maintainer sein kann oder will, ist die Aufgabe einen Nachfolgemaintainer zu finden einfacher, weil das Modul nicht unter die Kategorie "Oh Gott, was habe ich mir da eingehandelt" fällt.

Ich rede da aus Erfahrung.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 27 März 2020, 13:50:28
Zitat von: justme1968 am 27 März 2020, 12:15:47
auch wenn völlig klar ist welche der beiden lesbarer ist haben diese beiden beispiele absolut nichts mit der klamer verwendung für buildins zu tun. also thema verfehlt.

Die beiden Beispiele haben EXAKT damit zu tun, was mit dem FHEM code passiert, wenn man mit PBP Brille drüberrutscht. Thema nicht erkannt.
Vielleicht versuchen ein wenig Abstand zu gewinnen, dann sieht man auch einfacher das "big picture".

Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: SCMP77 am 27 März 2020, 16:30:27
Zitat von: RichardCZ am 27 März 2020, 12:07:12Ich finde es schon nett, wenn ich einen 5,6,7 Jahre alten Code von jemandem sehe, wo ich mich inhärent zurechtfinde, weil er so


$attr{$name}{unit_windspeed}      //= "km/h";
$attr{$name}{unit_solarradiation} //= "lux";
$attr{$name}{round}               //= 4;


und nicht so

    $attr{$name}{unit_windspeed} = "km/h"
      if ( !defined( $attr{$name}{unit_windspeed} ) );
    $attr{$name}{unit_solarradiation} = "lux"
      if ( !defined( $attr{$name}{unit_solarradiation} ) );
    $attr{$name}{round} = 4 if ( !defined( $attr{$name}{round} ) );


Du darfst hier auch nicht vergessen, es gibt hier viele Leute, welche sich nur (fast) zwangsweise mit Perl beschäftigt haben, weil sie für die eigene Haussteuerung ein bisher nicht vorhandenes Modul benötigt haben. Manch einer hat sich da eine ganz private Anwendung geschrieben, manch anderer hat es dann der Allgemeinheit zur Verfügung gestellt.

Das gilt jedenfalls für mich. Ich bin kein Perl-Experte und ehrlich, ich will es auch nicht werden, weil für mich eine datentypdefinitionslose Programmiersprache ein graus ist (zumindest bei größeren Projekten) und dieses Gewurschtel mit @$\ kommt dann noch dazu. Ja, Pointer gab es auch in C, aber ich war froh, dass man das dann bei C++ kaum mehr benötigte, nur noch referenziert oder nicht war dort noch wirklich sinnvoll. Bei Java hat man selbst diese Untersacheidung abgeschafft, bei Objekten arbeitet man immer mit Referenzen. Ich progarmmiere daher  Perl möglichst "Java-like", weil ich mich auch nicht in Perl tief einarbeiten will. Perl lässt einem eben die Freiheiten, dass man es mit ein paar mehr Zeilen dann auch zum Laufen bekommt. Müsste ich mich erst mit der Bedeutung von //= rumschlagen, hätte ich sicher einen  großen Bogen um FHEM gemacht. Perl erlaubt glücklicherweise es auch so zu schreiben:


if ( !defined( $attr{$name}{unit_windspeed} ) ) {
    $attr{$name}{unit_windspeed}= "km/h ";
}


Das ist noch umständlicher, als der von Dir bemängelte Code, ist aber eben fast so, wie ich es seit Jahrzehnten von C/C++/Java gewöhnt bin, ganz nach dem Perl-Motto ,,There is more than one way to do it".

Ich lerne gern auch bei Perl dazu, aber es muss auch wirklich einen tieferen Sinn ergeben.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 27 März 2020, 17:34:48
Zitat von: SCMP77 am 27 März 2020, 16:30:27
Du darfst hier auch nicht vergessen, es gibt hier viele Leute, welche sich nur (fast) zwangsweise mit Perl beschäftigt haben, weil sie für die eigene Haussteuerung ein bisher nicht vorhandenes Modul benötigt haben.

Ich vergesse das nicht und ich kann mir sehr gut vorstellen. dass es für so Manchen eine regelrechte Qual sein kann sich unter diesen Umständen mit Perl auseinanderzusetzen. In genau der Situation werden Witzchen wie "Perl ist von Bildschirmrauschen nicht zu unterscheiden" den Maintainern das Lächeln eher gefrieren lassen.

Mein Versuch ist daher zu zeigen (und wer will - auch konkret an seinem Code zu helfen - so lange der Zeitvorrat reicht) wie man den Code zumindest so sauber bekommt, dass wenigstens das "Entziffern" nicht schon die kognitive Last auffrisst - die man ja eigentlich für die Funktionalität braucht.

Von daher bin ich bei einigen Modulen ehrlich gesagt schwer beeindruckt, wie sich der Betreffende trotz dieser Qual (die man dem Code ansieht), dennoch durchgegraben hat und etwas auf die Beine gestellt hat.

Ich bin nicht hier um dieses Werk zu kritisieren, ich bin hier um ihm zu helfen - wenn er will - dass dieses Werk evtl. weniger Qual/weniger Supportaufwand und robuster wird und ihm nicht irgendwann komplett über den Kopf wächst oder auf die Füße fällt. Weil das ist dann die Situation, wo ein Modul verwaisen kann.

Zitat
Ich bin kein Perl-Experte und ehrlich, ich will es auch nicht werden,
...
Perl erlaubt glücklicherweise es auch so zu schreiben:


if ( !defined( $attr{$name}{unit_windspeed} ) ) {
    $attr{$name}{unit_windspeed}= "km/h ";
}


Das ist noch umständlicher, als der von Dir bemängelte Code, ist aber eben fast so, wie ich es seit Jahrzehnten von C/C++/Java gewöhnt bin, ganz nach dem Perl-Motto ,,There is more than one way to do it".

Ich lerne gern auch bei Perl dazu, aber es muss auch wirklich einen tieferen Sinn ergeben.

Also ich wiederhole noch einmal: Alles was wir hier besprechen ist optional.

Wer  if ( !defined( $attr{$name}{unit_windspeed} ) ) { $attr{$name}{unit_windspeed}= "km/h "; }
statt //= schreiben will, soll das machen. Wenn es dadurch ein Modul gibt, das zwar "Kraut & Rüben" Perl Code ist, aber mit Device X redet, dann ist das 100x besser, als gäbe es ein perfektes elegantes Perl Modul ... gar nicht.

Wie schon in den "Worten zur Motivation" gesagt: Egal wie der Code ist, es ist besser als wäre er nicht.




Ich bin auch kein Profi-Bauherr und will es ehrlich gesagt nicht werden, weil ein Haus reicht. Aber ich kenne den Unterschied zwischen Häusern, die Leute so mit "Bordmitteln" zusammengeschustert haben und Häusern, wo zumindest Profis zu Rate gezogen wurden. (kompetente Profis - nicht nur solche mit der Visitenkarte Profi).

Ich muss zwar dann darin wohnen, aber genau deswegen werde ich trotzdem eine Innenarchitektin meinen Wohnzimmer/Küche/Halle/Wintergarten/Pool/Bad-Erdgeschoss-Komplex projektieren lassen und da nicht selbst reinknödeln, Ich kann sagen was mir wichtig ist, aber ansonsten höre ich ihr sehr aufmerksam zu.
Titel: Antw:PBP: Warum sind Prototypen schlecht?
Beitrag von: RichardCZ am 06 April 2020, 14:32:21
Es sei angemerkt, dass wenn man erstmal die Prototypen los ist, dass es auch so etwas wie "Forward Deklaration" nicht gibt.

z.B. in fhem.pl - kann man ersatzlos knicken:

# configDB special
sub cfgDB_Init;
sub cfgDB_ReadAll;
sub cfgDB_SaveState;
sub cfgDB_SaveCfg;
sub cfgDB_AttrRead;
sub cfgDB_FileRead;
sub cfgDB_FileUpdate;
sub cfgDB_FileWrite;