Autor Thema: 99_Utils: undefined values  (Gelesen 339 mal)

Offline RichardCZ

  • Tester
  • Sr. Member
  • ****
  • Beiträge: 558
  • HoBo: zwischen Weltherrschaft und Intensivstation
    • Experimenteller FHEM Fork
99_Utils: undefined values
« am: 13 Mai 2020, 22:44:18 »
Ich weiß noch nicht wie ich es geschafft habe - vermutlich dunkle Experimente mit Mysensors (ohne Codeänderungen jedoch) - aber

2020.05.13 22:32:35 1: PERL WARNING: Use of uninitialized value $string in substitution (s///) at ./FHEM/99_Utils.pm line 109.
2020.05.13 22:32:35 1: PERL WARNING: Use of uninitialized value $string in substitution (s///) at ./FHEM/99_Utils.pm line 110.


Best guess ist, dass ich irgendwo was hardwaremäßig noch nicht richtig konfiguriert habe.
MYSENSOR_0 ??? erscheint.
Zumindest sind solche undefines vorher nicht aufgetaucht im Log.

sub trim($) {
    my $string = shift;
    $string =~ s/^\s+//;
    $string =~ s/\s+$//;
    return $string;
}

-> das übliche defined-or würde hier helfen:

sub trim($) {
    my $string = shift // return q{};
    $string =~ s/^\s+//;
    $string =~ s/\s+$//;
    return $string;
}

oder

sub trim($) {
    my $string = shift // return;
    $string =~ s/^\s+//;
    $string =~ s/\s+$//;
    return $string;
}

Welches davon man macht hängt davon ab welche Semantik man haben möchte.
Ersteres ist "self-healing", letzteres ist "konsistenter". Bei der Gelegenheit könnte
man das defined-or ja generell ein wenig mehr pflanzen.

Das ist z.B. eine der Sachen die ich meine, wenn ich sage FHEM code ist nicht robust.

Online herrmannj

  • Global Moderator
  • Hero Member
  • ****
  • Beiträge: 5605
Antw:99_Utils: undefined values
« Antwort #1 am: 13 Mai 2020, 23:00:37 »
? Wenn man trim mit undef aufruft bekommt man eine Warnung (keinen Fehler und keinen Absturz) dass man trim mit undef aufgerufen hat.
smartVisu mit fronthem, einiges an HM, RFXTRX, Oregon, CUL, Homeeasy, ganz viele LED + Diverse

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 22328
Antw:99_Utils: undefined values
« Antwort #2 am: 13 Mai 2020, 23:01:34 »
Zitat
Das ist z.B. eine der Sachen die ich meine, wenn ich sage FHEM code ist nicht robust.
Ich versuche bei Pruefungen abzuwaegen, ob es im Normalfall hilft, oder eher Performance kostet.
In diesem Fall tendiere ich dazu, das Problem nicht unter dem Teppich zu kehren, sondern die Ursache mit  "attr global stacktrace" zu lokalisieren.

Offline RichardCZ

  • Tester
  • Sr. Member
  • ****
  • Beiträge: 558
  • HoBo: zwischen Weltherrschaft und Intensivstation
    • Experimenteller FHEM Fork
Antw:99_Utils: undefined values
« Antwort #3 am: 13 Mai 2020, 23:24:43 »
? Wenn man trim mit undef aufruft bekommt man eine Warnung (keinen Fehler und keinen Absturz) dass man trim mit undef aufgerufen hat.

Wenn Perl eine Warnung ausspuckt ist das ein Fehler. Es gibt Firmen, da wird nach PBP vorgegangen und warnings werden generell fatal geschaltet.

Es ist eindeutig ein Fehler der trim Routinen. Sie erlauben den ungeprüften Erhalt eines undef (trotz glorreichem Protoyp) und können damit aber
nicht umgehen.

edit:

Also nein, man bekommt keine "Warnung, dass man Trim mit undef aufgerufen hat". Man bekommt eine Warnung, dass man versucht hat
einen undefinierten Wert in eine Substitution zu drücken. Das ist bereits zu spät.

Wenn man es unbedingt kontraproduktiv abfangen will kann man ja auch

my $string = shift // warn 'blah';

oder log oder sonstwas machen. Dann warnt man, dass man trim mit undef aufgerufen hat.


@Rudolf:

Ein defined-or ist auch nix unter den Teppich kehren. Ich gehe also davon aus man will keine self-healing Semantik (das ist ein wenig
unter den Teppich kehren). Dann also undef IN => undef OUT

edit2:

In diesem fall wird trim einen undef zurückliefern und jemand der trim benutzt bekommt nun wieder einen undef zurück (den er vorher reingestopft hat).
Das ist aber nicht mehr das Problem von trim. Die Warning wird dann vermutlich woanders hochblubbern, aber dann soll das ja auch der Verursacher fixen.
Trim ist dann aber fein (und korrekt) raus.

also

my $string = shift // return;

Best practice. Echt jetzt.
« Letzte Änderung: 13 Mai 2020, 23:39:46 von RichardCZ »

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 22328
Antw:99_Utils: undefined values
« Antwort #4 am: 13 Mai 2020, 23:44:42 »
Zitat
Ich gehe also davon aus man will keine self-healing Semantik
trim will einen String, wenn man stattdessen undef uebergibt, dann ist das ein Fehler beim Aufruf, und das Framework macht einen hoeflich darauf aufmerksam.
Mit der Pruefung waere ja nichts geheilt, irgendwas waere immer noch kaputt, man kriegt es nur nicht mit.

Offline RichardCZ

  • Tester
  • Sr. Member
  • ****
  • Beiträge: 558
  • HoBo: zwischen Weltherrschaft und Intensivstation
    • Experimenteller FHEM Fork
Antw:99_Utils: undefined values
« Antwort #5 am: 14 Mai 2020, 12:22:20 »
trim will einen String, wenn man stattdessen undef uebergibt, dann ist das ein Fehler beim Aufruf, und das Framework macht einen hoeflich darauf aufmerksam.
Mit der Pruefung waere ja nichts geheilt, irgendwas waere immer noch kaputt, man kriegt es nur nicht mit.

Also nochmal.

Trim will einen String. Ich will auch so manches, aber bekomme es nicht (immer).
Wenn Trim nun keinen String bekommt, sollte es nicht gleich eine Alkoholsucht entwickeln.
Ich bin ja hier auch schon seit 2 Monaten und habe es bisher geschafft diesen Drang zu unterdrücken.

Wie herrmann falsch schrieb und ich klarstellte: Trim warnt nicht davor dass man undef übergeben hat, trim lässt den undef gnadenlos ungeprüft auf den substitution Operator durchrauschen und DER beschwert sich - inhärentes Perl Feature, last resort - über diesen undef.

Ein guter Programmierer stellt sicher, dass man eben kein undef auf einen =~ loslässt.

Schon gemerkt, dass der Seitenaufprallschutz bei Fahrzeugen links genauso gut ist wie rechts? Dabei könnten die Autohersteller doch auf "Rechts-Vor-Links" Märkten so viele Tonnen Stahl einsparen... Schliesslich ist es da ja auch verboten von links in ein Fahrzeug reinzurauschen.



Aber ich bin da eigentlich schmerzfrei. So sieht ein 10+ Jahre alter Code bei uns in der Firma aus.
Notfals deichsel ich das so hin, dass ich den (und die ganze Lib dahinter) verwenden kann.

# {{{ s2s_trim_whitespaces         trim leading and trailing whitespace of string

sub s2s_trim_whitespaces {
    my $str = shift // return q{}; # get string to trim (bail out if not given)

    $str =~ s{\A\s+}{}xms;    # strip leading spaces
    $str =~ s{\s+\z}{}xms;    # strip trailing spaces

    return $str;              # return trimmed string
}

# }}}

Hier mit self-healing Semantik. Da war die Überlegung eben Garbage in- das Nächstsinnvolle raus.

Ich hoffe nur, man tut jetzt nicht in FHEM päpstlicher als der Papst mit undef != leerer String, weil dann
müsste ich doch recht herzhaft lachen.

 

decade-submarginal