FHEM Forum

FHEM => Sonstiges => Thema gestartet von: Navigator am 07 Mai 2020, 14:22:32

Titel: Meldung: called too early to check prototyp
Beitrag von: Navigator am 07 Mai 2020, 14:22:32
Hi...
ich bekomme bei einem Neustart von FHEM immer die Meldung:

PERL WARNING: main::GewHaus_Bewaesserung_pr() called too early to check prototype at ./FHEM/99_myUtils.pm

bezüglich einer meiner Sub´s in der myUtils.

An betreffender Zeile ruft die Sub sich selber wieder auf, mit zwei Parametern.
An sich funktioniert alles, aber aus der Meldung werde ich trotzdem nicht so recht schlau.  ???
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: MadMax-FHEM am 07 Mai 2020, 14:57:14
Wie wäre es dann deinen Code zu posten!?

Wie soll man sonst etwas dazu sagen... ;)

Gruß, Joachim
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Navigator am 07 Mai 2020, 15:03:02
oh ja.. gute Idee.  :)


sub GewHaus_Bewaesserung_pr($$) {

my $durchgang = shift;
my $programm = shift;
my $programm2 = "";
if ($programm == 1){
$programm2 = 2
}
elsif ($programm == 2){
$programm2 = 1
}

$durchgang = $durchgang + 1;
my $stunde=(localtime)[2];
my $minute=(localtime)[1];
$minute="0$minute" if $minute < 10;
my $planungsstatus = ReadingsVal("GewHaus_Bewaesserung_Kreis_Vorwahl_pr$programm","kreis$durchgang","");
if (Value("GewHaus_Bewaesserung_Kreis_Vorwahl_pr$programm2") eq "off"){
Log 1, "Gewächshaus Bewässerung gestartet" if $durchgang == 1;
if ($durchgang <= 2) {
if ($planungsstatus eq "eingeplant"){
my $dauer = ReadingsVal("GewHaus_Bewaesserung_Kreis_Vorwahl_pr$programm","dauer$durchgang","");
$dauer = "0$dauer" if $dauer < 10;
Log 1, "Gewächshaus Bewässerung Programm $programm Kreis $durchgang gestartet";
fhem ("set GewHaus_Bewaesserung_Kreis_Vorwahl_pr$programm on;set HMW_GewHaus_Kreis_$durchgang on;setreading GewHaus_Bewaesserung_Kreis_Vorwahl_pr$programm status$durchgang ...beim bewässern seit $stunde:$minute Uhr");
fhem ("define A_GewHaus_Bewaesserung_Ende_Kreis_$durchgang at +00:$dauer setreading GewHaus_Bewaesserung_Kreis_Vorwahl_pr$programm status$durchgang Start $stunde:$minute Uhr - abgeschlossen;;
set HMW_GewHaus_Kreis_$durchgang off;;sleep 2;;set HMW_GewHaus_Kreis_$durchgang off");
my $nextbegin = $dauer - 1;
$nextbegin = "0$nextbegin" if $nextbegin < 10;
fhem ("define A_GewHaus_Bewaesserung_Next_Kreis_$durchgang at +00:$nextbegin:55 {GewHaus_Bewaesserung_pr ($durchgang,$programm)}");
}
elsif ($planungsstatus eq "ausgegliedert"){
Log 1, "Gewächshaus Bewässerung Programm $programm Kreis $durchgang übergangen";
fhem ("setreading GewHaus_Bewaesserung_Kreis_Vorwahl_pr$programm status$durchgang übergangen");
GewHaus_Bewaesserung_pr($durchgang,$programm);
}
}
if ($durchgang == 3) {Log 1, "Gewächshaus Bewässerung Programm $programm beendet";
    fhem ("set GewHaus_Bewaesserung_Kreis_Vorwahl_pr$programm off");
fhem ("set GewHaus_Bewaesserung_Manuell_pr$programm off") if (Value("GewHaus_Bewaesserung_Manuell_pr$programm") ne "off");
fhem ("defmod A_GewHaus_Bewaesserung_Ausgaenge_Check1 at +00:00:20 {for my \$i (1..2){fhem (\"get HMW_GewHaus_Kreis_\$i state\")}}");
fhem ("defmod A_GewHaus_Bewaesserung_Ausgaenge_Check2 at +00:00:25 {
if (Value(\"GewHaus_Bewaesserung_Kreis_Vorwahl_pr1\") eq \"off\"
&& Value(\"GewHaus_Bewaesserung_Kreis_Vorwahl_pr2\") eq \"off\") {
for my \$i (1..2) {if (Value(\"HMW_GewHaus_Kreis_\$i\") ne \"on\" && Value(\"HMW_GewHaus_Kreis_\$i\") ne \"off\"){
fhem (\"set HMW_GewHaus_Kreis_\$i off\");;
Log 1, \"Ausgang HMW_GewHaus_Kreis_\$i vermutlich nicht abgeschalten - schalte ab\"}}}}")
}
}
else {
Log 1, "Kein Start Bewaesserung Programm $programm - anderes Programm in Betrieb";
fhem("set GewHaus_Bewaesserung_Manuell_pr$programm off")
}
}


Der Fehler entsteht in Zeile...

GewHaus_Bewaesserung_pr($durchgang,$programm);
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Christoph Morrison am 07 Mai 2020, 15:05:28
Du brauchst keine Prototypen und dann ist dein Problem auch gelöst.
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Navigator am 07 Mai 2020, 15:12:31
Zitat von: Christoph Morrison am 07 Mai 2020, 15:05:28
Du brauchst keine Prototypen und dann ist dein Problem auch gelöst.
Könntest du das etwas genauer schildern? Ich muss ja genau zwei Werte übergeben.
Sind die Prototypen nicht explizit dafür gedacht um die richtige Anzahl an geforderten Parametern zu definieren?
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Christoph Morrison am 07 Mai 2020, 15:34:47
Zitat von: Dittel am 07 Mai 2020, 15:12:31
Könntest du das etwas genauer schildern? Ich muss ja zwei Werter übergeben, was genau und wie sollte ich deiner Meinung nach ändern.

Ja. Du nimmst statt

sub GewHaus_Bewaesserung_pr($$) {

einfach

sub GewHaus_Bewaesserung_pr {

Die beiden $ sind die Prototyp-Definitionen (https://perldoc.perl.org/perlsub.html#Prototypes). Und da du nicht mal weißt für was die gut sind, kannst du sie auch weglassen. Deine Funktion wird weiterhin zwei Parameter akzeptieren.
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: MadMax-FHEM am 07 Mai 2020, 15:40:56
Zitat von: Christoph Morrison am 07 Mai 2020, 15:34:47
Deine Funktion wird weiterhin zwei Parameter akzeptieren.

Und sogar mehr oder weniger ;)

Es kommt drauf an was du mittels shift tust bzw. aus dem Aufruf "rausholst"... ;)

Gruß, Joachim
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Navigator am 07 Mai 2020, 15:43:36
Nun ich war bisher immer im Glauben Perl braucht die Prototypen um die Anzahl der übergebenen Parameter zu kennen. Jeweils ein Prototype für einen Parameter und für optionale Parameter ein ;$. So habe ich es zumindest gelernt.

Was ist wenn ich die Parameter nicht mit "shift" sonder über "@_" ausgelsesen hätte. Hätte ich die Prototypen dann gebaucht?
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Christoph Morrison am 07 Mai 2020, 15:45:15
Zitat von: MadMax-FHEM am 07 Mai 2020, 15:40:56
Und sogar mehr oder weniger ;)

Spannend auch was geschieht wenn man einfach gar nix übergibt (https://de.wikipedia.org/wiki/Defensives_Programmieren). Hast du das mal getestet?
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: MadMax-FHEM am 07 Mai 2020, 15:46:40
Vielleicht hilft das: https://forum.fhem.de/index.php/topic,109526.msg1035022.html#msg1035022 ;)

Gruß, Joachim
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: MadMax-FHEM am 07 Mai 2020, 15:48:53
Zitat von: Christoph Morrison am 07 Mai 2020, 15:45:15
Spannend auch was geschieht wenn man einfach gar nix übergibt (https://de.wikipedia.org/wiki/Defensives_Programmieren). Hast du das mal getestet?

Nö ;)

Aber ich komme aus einer Welt wo OHNE Prototypen nix geht...

Da mosert ja der (Pre)Compiler...

Drum (ungeachtet des verlinkten Threads: mag bei Perl so sein / aber da es nicht schadet ;)  ) nutze ich weiterhin Prototypen...
...bin aber ja auch kein Modulauthor und was ich "bei mir" an Code "fabriziere" geht niemanden was an ;)

Gruß, Joachim
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Christoph Morrison am 07 Mai 2020, 15:49:50
Zitat von: Dittel am 07 Mai 2020, 15:43:36
Was ist wenn ich die Parameter nicht mit "shift" sonder über "@_" ausgelsesen hätte. Hätte ich die Prototypen dann gebaucht?

Nein.
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Christoph Morrison am 07 Mai 2020, 15:53:13
Zitat von: MadMax-FHEM am 07 Mai 2020, 15:48:53
Drum (ungeachtet des verlinkten Threads: mag bei Perl so sein / aber da es nicht schadet ;)  ) nutze ich weiterhin Prototypen...

Lustig das in einem Thread zu schreiben, in dem der OP genau wegen (nutzloser) Prototypen ein Warning bekommt ;-)
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: MadMax-FHEM am 07 Mai 2020, 15:54:02
Zitat von: Christoph Morrison am 07 Mai 2020, 15:53:13
Lustig das in einem Thread zu schreiben, in dem der OP genau wegen (nutzloser) Prototypen ein Warning bekommt ;-)

Tja ;)
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: KölnSolar am 07 Mai 2020, 15:56:14
Zitatbin aber ja auch kein Modulauthor und was ich "bei mir" an Code "fabriziere" geht niemanden was an ;)
und leserlicher ist es allemal....  8)
Nur interessiert das Perl-Gurus nicht. :o
Grüße Markus
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: CoolTux am 07 Mai 2020, 15:58:29
Die leserlichkeit kann man aber beeinflussen

sub test {        # (var1,var2)

}
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: rudolfkoenig am 07 Mai 2020, 15:59:45
Fuer die, die Prototypen verwenden wollen, und bereit sind, den neuerdings deswegen hier ueblichen Shitstorm zu ignorieren:
bei einem rekursiven Aufruf muss man vor der Funktionsdefinition sie nochmal deklarieren
sub GewHaus_Bewaesserung_pr($$);
sub GewHaus_Bewaesserung_pr($$) {
....
}
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Navigator am 07 Mai 2020, 16:09:37
Nun es ist auch für mich etwas ungewohnt nicht zu wissen wie viele Parameter ich übergeben kann, sollte oder habe wenn ich die Prototypes weg lasse. Ich frage mich nur was mich bewogen hat es immer "falsch" ?! zu machen. Irgendein Perl Buch muss es mir eben ganau so eingetrichtert haben oder hat sich an der Handhabung da mal was geändert?

Das Thema scheint ja ziemlich sensibel zu sein.  ;D
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Christoph Morrison am 07 Mai 2020, 16:14:40
Zitat von: rudolfkoenig am 07 Mai 2020, 15:59:45
Fuer die, die Prototypen verwenden wollen, und bereit sind, den neuerdings deswegen hier ueblichen Shitstorm zu ignorieren:
bei einem rekursiven Aufruf muss man vor der Funktionsdefinition sie nochmal deklarieren
sub GewHaus_Bewaesserung_pr($$);
sub GewHaus_Bewaesserung_pr($$) {
....
}


Da hat man ja total was gewonnen! Mehr Code um ein Warning loszuwerden, das man mit weniger Code überhaupt nicht hätte. Und dann ändert man was an GewHaus_Bewaesserung_pr, vergisst die Dublette und bums.

Mich würde mal interessieren, wie der OP überhaupt dazu gekommen ist, Prototypen zu verwenden?
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: MadMax-FHEM am 07 Mai 2020, 16:14:47
Zitat von: rudolfkoenig am 07 Mai 2020, 15:59:45
Fuer die, die Prototypen verwenden wollen, und bereit sind, den neuerdings deswegen hier ueblichen Shitstorm zu ignorieren:
bei einem rekursiven Aufruf muss man vor der Funktionsdefinition sie nochmal deklarieren
sub GewHaus_Bewaesserung_pr($$);
sub GewHaus_Bewaesserung_pr($$) {
....
}


So wie ich es in "meiner" Welt kenne:

Prototyp ins h-File
Implementierung ins C(++)-File

Gruß, Joachim
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: CoolTux am 07 Mai 2020, 16:16:19
Zitat von: Dittel am 07 Mai 2020, 16:09:37
Nun es ist auch für mich etwas ungewohnt nicht zu wissen wie viele Parameter ich übergeben kann, sollte oder habe wenn ich die Prototypes weg lasse. Ich frage mich nur was mich bewogen hat es immer "falsch" ?! zu machen. Irgendein Perl Buch muss es mir eben ganau so eingetrichtert haben oder hat sich an der Handhabung da mal was geändert?

Das Thema scheint ja ziemlich sensibel zu sein.  ;D


Es ist nicht sensibel. Und wenn Du mit Prototypen arbeiten willst dann mach es, ist ok.
Frühere Perlbücher so bis 2006 glaube haben das auch noch so gemacht. Alles danach arbeitet komplett ohne.
Beispiel: Der Perl Programmierer
Dicker Wälzer. Wieso es empfohlen wird ohne Prototypen zu arbeiten kann man in Perl Best Praxis nach lesen.

Man kann einfach sagen es ist eine modernere Form für Perl. Gut zu lesen im Buch Modern Perl von 2014.


Grüße
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Navigator am 07 Mai 2020, 16:27:40
ZitatMich würde mal interessieren, wie der OP überhaupt dazu gekommen ist, Prototypen zu verwenden?


Als ich ich mit Fhem und Perl angefangen habe, waren mir nur die Sprache BASIC geläufig aus früheren C64 Kindertagen. Dann kam mit Perl ja gleich mal der Hammer und ich hab mich mit einer Ausgabe von 2005 "Mit Perl programmieren lernen" mal wieder an die Sache herangetraut. Dort muss es sich wohl festgesetzt haben, Parameter zu "zählen". Da ich aber rein privat noch wilden Code in Python schreibe, war mir das nicht fremd und auch dort ist es in ähnlicher Form ja gegeben. Das jetzt im nachhinein wieder "umzubiegen" ist ja wie schreiben lernen mit links.  :o
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: CoolTux am 07 Mai 2020, 16:33:28
Auch in Perl gab es mehrere Rechtschreibreformen  ;D
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Navigator am 07 Mai 2020, 16:43:38
Zitat von: CoolTux am 07 Mai 2020, 16:33:28
Auch in Perl gab es mehrere Rechtschreibreformen  ;D

Dann würde ich auch hier wohl eher zu den Rebellierenden gehören.
Hab gerade mal ohne die Prototypes getestet und mal einen Parameter weggelassen.
Ich bekomme dann eine Fehlermeldung, die ohne den Code zu sichten erst mal nicht schlüssig ist.
Please define GewHaus_Bewaesserung_Manuell_pr first

Mit der Prototype Option weiß man dagegen sofort was klemmt.
Not enough arguments for main::GewHaus_Bewaesserung_pr at (eval 530) line 1, near "1)"

Ein Hoch auf die Prototypes.  ;D
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Christoph Morrison am 07 Mai 2020, 16:56:20
Zitat von: Dittel am 07 Mai 2020, 16:43:38
Dann würde ich auch hier wohl eher zu den Rebellierenden gehören.
Hab gerade mal ohne die Prototypes getestet und mal einen Parameter weggelassen.

Niemand hat gesagt, dass du dich darauf verlassen sollst, dass immer x Parameter kommen. Denn du musst sowieso checken, ob die Parameter auch inhaltlich valide sind. Übergib doch mal undef oder irgendeinen Müll an die Funktion und du bekommst auch einen Fehler - weil deine sanity checks nicht wirklich existieren. Dazu bekommst du mit Prototypes aber auch noch unsichtbare magic:


perl -MData::Dumper -e 'sub t($$) { print Dumper(@_); }; t(1,(2,3,5));'
$VAR1 = 1;
$VAR2 = 5;


Hättest du das erwartet?
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: rudolfkoenig am 07 Mai 2020, 17:04:25
Ja, man kann abstruse Faelle konstruieren, wo nicht das passiert, was man erwartet.
Aber so wie ich denke und programmiere, sind die fuer mich hilfreich.
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Navigator am 07 Mai 2020, 17:29:07
Zitat von: Christoph Morrison am 07 Mai 2020, 16:56:20

Hättest du das erwartet?

Ähm, nein aber ein interessantes Beispiel. Das muss ich mal zerplücken und schauen warum das so ist.
Zitat von: Christoph Morrison am 07 Mai 2020, 16:56:20
- weil deine sanity checks nicht wirklich existieren.

Ja das stimmt, darauf sollte ich in Zukunft mehr Wert legen. Eigentlich waren meine Codeschnipsel immer soweit getestet und konsistent, daß größeres Fehlverhalten mir bisher erspart blieb. Aber ich möchte nicht wissen, was passiert wenn mal das Fhem statefile nicht aktuell ist oder verloren geht. Dann ist das Chaos erst einmal perfekt und das Haus lernt fliegen.
Inwieweit man aber auf jede erdenkliche Fehleingabe oder Situation eine Ausnahmebehandlung schreiben sollte sei mal dahingestellt und kommt wohl auf die angestrebte Funktion an. Bei einer Bewässerung ist dies wohl aber sehr wohl mehr von Bedeutung als bei einer Routine für ein paar Lampen.
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Christoph Morrison am 07 Mai 2020, 18:44:08
Zitat von: rudolfkoenig am 07 Mai 2020, 17:04:25
Ja, man kann abstruse Faelle konstruieren, wo nicht das passiert, was man erwartet.
Aber so wie ich denke und programmiere, sind die fuer mich hilfreich.

In deiner Welt sind alles nur "abtruse Fälle" damit du ja nie hinterfragen musst, ob dein bisher Gelerntes vielleicht nicht nur einfach nicht mehr dem aktuellen Stand - also dem von 2005 oder wann PBP erschienen ist - entspricht. So ist es natürlich schön bequem.
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: rudolfkoenig am 07 Mai 2020, 19:18:12
Vielen Dank fuer den persoenlichen Angriff.
Du kennst mich schliesslich am besten.
Titel: Antw:Meldung: called too early to check prototyp
Beitrag von: Christoph Morrison am 07 Mai 2020, 19:58:06
Zitat von: rudolfkoenig am 07 Mai 2020, 19:18:12
Vielen Dank fuer den persoenlichen Angriff.
Du kennst mich schliesslich am besten.

Ach ja, aber "abstruse Fälle" ist natürlich professioneller, nicht-persönlicher Umgang, genau wie das Abqualifizieren von von dir ungeliebten Meinungen als "Shitstorm" (offensichtlich hast du noch keinen erlebt).

Dafür, dass du selbst gerne austeilst hast du aber ein ganz schön dünnes Fell.