Wunschlliste Themen

Begonnen von Wzut, 28 März 2020, 19:53:24

Vorheriges Thema - Nächstes Thema

Wzut

Sind vllt. Themen die nicht unbedingt unter PBP fallen , aber ich mir einbilde irgendwo mal etwas dazu zu gelesen zu haben und eventuell klar gestellt werden können.

a. $s = 'Test Nr '.$i.' bestanden'  vs. "Test Nr $i bestanden"
Ich tippe mir teilweise die Finger wund weil ich Strings von " auf einfaches Hockomma umbaue.
Grund : irgendwo gelesen das würde Perl entlasten, da nicht nach Variablen gesucht wird. Mythos oder Wahrheit ?

b. $i += 1  vs. $i++
++ ist angeblich effektiver ,    M o W ?

c.  int($i)  vs. $i++; $i--; 
der schnellste Weg eine Variable numerisch zu bekommen,   M o W ?

d. Substring im String suchen : grep vs. index()  ,
ich verwende wo immer es geht index,  ist schneller als grep ?

 
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

RichardCZ

#1
Zitat von: Wzut am 28 März 2020, 19:53:24
Sind vllt. Themen die nicht unbedingt unter PBP fallen , aber ich mir einbilde irgendwo mal etwas dazu zu gelesen zu haben und eventuell klar gestellt werden können.

Finde ich sehr gut! Ich habe teilweise den Eindruck, dass ich hier viel Sermon ablasse, Konkrete Fragestunde wo Leute was drückt wäre doch mal zur Abwechslung besser.

Zitat
a. $s = 'Test Nr '.$i.' bestanden'  vs. "Test Nr $i bestanden"

letzteres

Zitat
Grund : irgendwo gelesen das würde Perl entlasten, da nicht nach Variablen gesucht wird. Mythos oder Wahrheit ?

Es wird wohl homöopatisch schneller sein, aber es ist (wird auch im PBP empfohlen) für den Maintainer eine wesentliche Entlastung, weil er gleich sieht ob der String interpoliert oder nicht.

Also:

my $str = 'tralala'; # nicht: "tralala"
my $str = "aha $tralala bebe"; # nicht 'aha ' . $tralala . ' bebe'
my $str = $aha . $bebe;   # ist ok
my $str = "$aha$bebe";   # ist genauso ok

Pro Tipp:

my $string = q{Hier kann's echt "dicke" stehen.};

Dann stellt man fest, man möchte doch eine Variable drin interpolieren:

my $string = qq{Hier kann's echt "dicke" stehen: $tralala};

Ein q vorne dazu oder weg und fertig. Überdies muss man keine Angst vor " oder ' im String haben.


Zitat
b. $i += 1  vs. $i++
++ ist angeblich effektiver ,    M o W ?

Effizienter.  ;)  Beide sind gleich effektiv.
Wahrheit. $i += 2 ist aber effizienter als $i++; $i++ und wesentlich effizienter als $i = $i + 2;
Auch Wahrheit: ++$i ist schneller als $i++;

Aber der wahre Vorteil ist hier nicht geschwindigkeit. Der Wahre Vorteil sind Subtilitäten wie

if (++$variable < 5)
oder
if ($variable++ < 5)

Echte Programmierer können da dann sehr eleganten Code schreiben. Ist aber nicht Perl spezifisch.


Zitat
c.  int($i)  vs. $i++; $i--; 
der schnellste Weg eine Variable numerisch zu bekommen,   M o W ?

Numerisch oder Integer? numerisch: $var+0
Integer: int($var)

Zitat
d. Substring im String suchen : grep vs. index()  ,
ich verwende wo immer es geht index,  ist schneller als grep ?

grep und index sind zwei verschiedene Dinge.
grep filtert eine Liste, index sucht einen substring.
Also index.
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

Wzut

THX, dann wäre das schon mal soweit klar.
Bei c. hatte ich mich blöd ausgedrückt, es ging mir da nicht um $i++ oder $i-- sondern um $i++ und $i--
Das sieht zwar auf den ersten Blick bescheuert aus , erst eins drauf dann gleich wieder weg, aber der Myhtos besagte das so der Perl Compiler den Assembler Code INC und DEC erzeugen würde ... ja Anfang der 80er was CPU Power und Speicherplatz noch ein rares Gut :)
das $var+0 nutze ich heute schon, meist nach einem sprintf("%.1", $var) wenn ich ordenliche Zahlen wie 1,2,3 haben will und keine 1.0, 2.0 usw.
 
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

Wzut

Ich mach mal mit dem Thema shift und @_ hier weiter da es im return undef Thread doch OT ist :
Es ging um : my ( $hash, $name) = @_;    vs.   my $hash = shift; my $name = shift; und wo die Grenze liegen sollte wie oft man shift nutzt.
Richards Antwort war :
ZitatDie 3 und mehr Argumente ist eher die Grenze um zu named Arguments überzugehen, weil positionale Parameter ihre Vorteile (Kürze/Würze) verlieren:

= @_; macht man eigentlich nur, wenn man tatsächlich eine Liste übergibt aber selbst das macht man nicht, weil man eine listreferenz übergeben sollte. (Um den Stack nicht immer vollzukleistern)

zu : macht man eigentlich nur, wenn man tatsächlich eine Liste übergibt
Konkret -> die Attr Funktion in einem Modul , i.d.R. sieht die so aus : my ($cmd, $name, $attrName, $attrVal) = @_;
Nun die Preisfrage , was liefert mir den da @_ eine Liste oder eine listrefrenz ? (das mit den Referenzen kommt die Tage hier so oft das das schon wieder ein Thema wert wäre)
Und ob es nun Fisch oder Fleisch ist, irgendwie bin ich doch zu doof für das Thema, denn bei Perlcritc -4 bekomme ich es wieder vorgesetzt und dann mit :
ZitatAlways unpack @_ first at line xyz, column 1.  See page 178 of PBP.  (Severity: 4)


Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

RichardCZ

Zitat von: Wzut am 30 März 2020, 10:59:10
Konkret -> die Attr Funktion in einem Modul , i.d.R. sieht die so aus : my ($cmd, $name, $attrName, $attrVal) = @_;
Nun die Preisfrage , was liefert mir den da @_ eine Liste oder eine listrefrenz ?

Liefert eine Liste. Das ist aber nunmal so und das wird sich auch nicht ändern. Der Vorschlag ist auch nicht aus

my ($cmd, $name, $attrName, $attrVal) = @_;

nur ein

my $cmd      = shift;
my $name     = shift;
my $attrName = shift;
my $attrVal  = shift;


zu machen, denn das wäre zu kurz gegriffen. Da man nun jedes Argument individuell vom Stack holt, kann man auch gleich validieren. Also an Stelle eines

my ($cmd, $name) = @_

return '' if (! defined $cmd);
$name = 'Gonzo' if (!$name);
...


Macht man eben

my $cmd  = shift // return '';
my $name = shift || 'Gonzo'


Nicht nur ist die zweite Form kürzer und übersichtlicher, sie ist auch effizienter, denn für den Fall dass $cmd undefiniert ist, muss man auch nicht sinnlos $name vom Stack holen, nur um ihn später wegzuschmeissen. Es wird schon vorher aus der Sub gesprungen.

Also lautet meine Empfehlung ein xxx = @_ nur dann zu shifts zu transformieren, wenn man gleich drunter im Code irgendwelche if (! defined $arg) bzw. if (! $arg) Validierungen oder Default-Initialisierungen der Argumente entdeckt, die man auf diese Art und Weise gleich abfackeln könnte.

Zitat
denn bei Perlcritc -4 bekomme ich es wieder vorgesetzt und dann mit :
Always unpack @_ first at line xyz, column 1.  See page 178 of PBP.  (Severity: 4)

Diese Meldung kommt, weil die Verwendung von $_[0], $_[1] etc. praktisch immer eine schlechte Idee ist. PBP Seite 178-181 erklärt.
Wer das Buch nicht hat, geht krass in Ukraine und guggt sich dort um: ftp://ftp.happy.kiev.ua/pub/doc/
oder kauft es oder glaubt mir.
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

Wzut

@Richard irgendwie reden wir gerade eineinader vorbei.
a. Ich sprech direkt die Attr Funktion an die man als Autor in sein Modul einbauen kann, dort muss ich nicht groß auf valide Parameter prüfen das macht fhem.pl schon für mich. D.h. ich muss jetzt mit den vier Werten arbeiten und Entscheidungen treffen. Meist in zwei Blöcken , ala wurde eben ein Attribut zugefügt/geändert (cmd set) oder eines gelöscht (cmd del) usw. usw

b. der eigentlich Grund für den Post  war :
my ($cmd, $name, $attrName, $attrVal) = @_;
Selbst PBP hat das so auf Seite 179
my ($text, $cols_count, $want_centering) = @_;

wo ist da jetzt der Unterschied zu meiner Zeile ?  Und nein ich greife dort nicht auf $_[0] zu (das war in einem anderen Thread, Beispiel) und da schreibt PBP ja auch :
auf Seite 178 :
ZitatBut accessing them via $_[0] , $_[1] , etc. directly is almost always a Very Bad Idea.

Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

RichardCZ

Zitat von: Wzut am 30 März 2020, 19:05:06
@Richard irgendwie reden wir gerade eineinader vorbei.

Um das zu vermeiden am besten Link auf das gesamte File senden oder es hier anhängen, damit ich lokal sehen kann woher das Problem kommt. Diese 1-Zeilen Excerpts sind wie ne Peep Show durch ein verstaubtes Schlüsselloch.
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

Wzut

Das mit dem Staub ist schon ok, denn glaube mir wenn der alte Herr dahinter die Hosen runter lässt das willst du gar nicht so genau sehen :)
Aber ok, es gilt doch noch der alte Spruch "wer lesen kann ... " , in dem Fall ich, denn ich war zu fixiert auf das @_ Thema, aber in Wahrheit bezieht sich die Meldung auf ein Stück tiefer im Code :
$_[3] = $hash->{type};
Die Zeile entstand durch https://wiki.fhem.de/wiki/DevelopmentModuleIntro
ZitatZusätzlich ist es möglich auch übergebene Attributwerte zu verändern bzw. zu korrigieren, indem man im Parameterarray @_ den ursprünglichen Wert anpasst. Dies erfolgt im Beispiel über die Modifikation des Wertes mit Index 3 (entspricht dem 4. Element) im Parameterarray, also $_[3]
Und genau das passiert hier, d.h. der übergebene Wertr passt mir an der Stelle nicht , also wird er überbügelt.
Die eigentliche Frage ist aber nun  : Wie bekommt man genau dieses Verhalten hin bleibt aber PBP konform ?

Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

RichardCZ

Zitat von: Wzut am 31 März 2020, 09:15:05
Das mit dem Staub ist schon ok, denn glaube mir wenn der alte Herr dahinter die Hosen runter lässt das willst du gar nicht so genau sehen :)
Aber ok, es gilt doch noch der alte Spruch "wer lesen kann ... " , in dem Fall ich, denn ich war zu fixiert auf das @_ Thema, aber in Wahrheit bezieht sich die Meldung auf ein Stück tiefer im Code :
$_[3] = $hash->{type};
Die Zeile entstand durch https://wiki.fhem.de/wiki/DevelopmentModuleIntroUnd genau das passiert hier, d.h. der übergebene Wertr passt mir an der Stelle nicht , also wird er überbügelt.
Die eigentliche Frage ist aber nun  : Wie bekommt man genau dieses Verhalten hin bleibt aber PBP konform ?

my $val1 = 3;

by_reference(\$val1);

print "Val1: $val1\n";


sub by_reference {
    my $arg1 = shift;

    $$arg1 *= 2;

    return;
}


gibt 6 aus. Perlcritic schweigt.
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

Wzut

ja nehme ich dein Beispiel direkt läuft das, aber angepasst auf das FHEM Umfeld mit zusätzlich use strict und dann by_reference($val1);
wird daraus
Can't use string ("3") as a SCALAR ref while "strict refs" in use at ./test.pl line 13
und genau das gleiche passiert als Totalabsturz in FHEM wenn ich
$$attrVal = 'test'  schreibe. Vermutlich weil in fhem,pl steht
$ret = CallFn($sdev, "AttrFn", "set", $sdev, $attrName, $attrVal);
und das kann man nicht einfach mal schnell in $ret = CallFn($sdev, "AttrFn", "set", $sdev, $attrName, \$attrVal); ändern, da dann FHEM gar nicht mehr startet.

Ich habe die Zeile jetzt ganz entfernt und gebe nur return 'Fehlermeldung';  zurück

Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

RichardCZ

#10
Zitat von: Wzut am 31 März 2020, 19:04:03
ja nehme ich dein Beispiel direkt läuft das, aber angepasst auf das FHEM Umfeld mit zusätzlich use strict und dann by_reference($val1);
wird daraus
Can't use string ("3") as a SCALAR ref while "strict refs" in use at ./test.pl line 13
und genau das gleiche passiert als Totalabsturz in FHEM wenn ich
$$attrVal = 'test'  schreibe. Vermutlich weil in fhem,pl steht
$ret = CallFn($sdev, "AttrFn", "set", $sdev, $attrName, $attrVal);

(Das hat jetzt gedauert, bis ich es geschafft habe die Forumssoftware zu verarschen, damit sie $_⦋x⦌ im Fliesstext anzeigt.)

Also wenn man ein Argument nicht "by Reference" übergibt, sondern "normal", dann ist der einzige, der darauf eine Referenz abbildet @_!
Folglich ist auch $_⦋x⦌  dann die einzige Möglichkeit dieses Argument en-passant zu verändern.
Das ist aber in etwa so, als würde man die Anleitung geben wie man Sarin herstellt.

shift und $_⦋x⦌  gehen gar nicht zusammen. Wer sich erinnert, ich habe mal geschrieben, dass shift die Argumentliste "konsumiert" und dass man das will. Eben damit da keine Referenzen in der Sub rumfleuchen. Hat man das mit shift gemacht, findet  $_⦋x⦌  i.d.R. nix mehr auf dem Stack (und für gewöhnlich ist das eine gute Sache)

Der übliche "wenn es gar nicht anders geht" Ratschlag lautet dann: ja, $_⦋x⦌  zusammen mit = @_ verwenden, wie es die ModuleIntro Doku sagt. Aber in Wirklichkeit möchte man da vielleicht eine bessere API - wo z.B. von einer CallFnNextGen eine Hashref zurückgegeben wird mit reichhaltigem Frühstück.

Gutes Design ist, wenn Argumente in die Sub reinkommen und dann via Return was rauskommt und Daten nicht noch durch diverse und Lecks "en passant" verändert werden. Man sieht ja dem CallFn Aufruf nicht an, dass er das Argument verändert. Schon gar nicht sieht man ihm an ob er es immer oder nur manchmal verändert.

my ($x, $y, $z) = @_

$_[2] = complex($z);
...


Konnte ich jetzt mein lokales perlcritic nicht dazu bekommen zu meckern.
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

Wzut

Zitat von: RichardCZ am 31 März 2020, 20:40:55
shift und $_⦋x⦌  gehen gar nicht zusammen.
---snipp ----
Der übliche "wenn es gar nicht anders geht" Ratschlag lautet dann: ja, $_⦋x⦌  zusammen mit = @_ verwenden, wie es die ModuleIntro Doku sagt
--- snipp ---
Konnte ich jetzt mein lokales perlcritic nicht dazu bekommen zu meckern.
a. OK , wieder was gelernt.
b. an der Stelle sollte man sich vllt. genau überlegen ob es überhaupt sein muß $_[3] anzufassen oder ob es nicht reicht direkt mit return $error zu verhindert das das Attribut geändert wird.
c. hmm das wäre dann nun schon der zweite Fall wo mein 5.24.1 und percritic nicht so recht zusammen wollen.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

RichardCZ

Zitat von: Wzut am 01 April 2020, 07:32:11
c. hmm das wäre dann nun schon der zweite Fall wo mein 5.24.1 und percritic nicht so recht zusammen wollen.

Wobei sich hier die kategorische Frage stellt, warum man bewusst eine kaputte Perl Version verwendet.
https://perldoc.perl.org/index-history.html

5.24.4 wenn es schon 5.24 sein muss.
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

mahowi

Zitat von: RichardCZ am 01 April 2020, 08:14:02
Wobei sich hier die kategorische Frage stellt, warum man bewusst eine kaputte Perl Version verwendet.
https://perldoc.perl.org/index-history.html

5.24.4 wenn es schon 5.24 sein muss.

Vermutlich läuft sein System unter Debian Stretch, da ist 5.24.1 noch aktuell:
Zitat von: https://packages.debian.org/de/stretch/perlPaket: perl (5.24.1-3+deb9u6)

Bei Buster läuft 5.28.1.
CUBe (MAX): HT, FK | CUBe (SlowRF): ESA2000WZ
JeeLink: LaCrosse | nanoCUL433: Smartwares SHS-51001-EU, EM1000GZ
ZME_UZB1: GreenWave PowerNode, Popp Thermostat | SIGNALDuino: HE877, X10 MS14A, Revolt NC-5462,  IT Steckdosen + PIR
tado° | Milight | HUE, Lightify | SmarterCoffee

RichardCZ

Zitat von: mahowi am 01 April 2020, 08:30:19
Vermutlich läuft sein System unter Debian Stretch, da ist 5.24.1 noch aktuell:
Bei Buster läuft 5.28.1.

Gut, bei Debian weiß man immer nie so genau, was das "-3" nach 5.24.1 bedeutet. Gibt's bestimmt irgendwo changelogs, könnten Backports der kritisch(st)en Fixes sein. Man verwendet - als Entwickler schon gar nicht - ja auch das OS Perl.

Perlbrew (https://perlbrew.pl/) Leute...

# perlbrew list
* 5.30                                     
  perl-5.30.1                               
  5.28                                     
  perl-5.28.0                               
  5.26                                     
  perl-5.26.0 


ein perlbrew  use <version> und schon hat man umgeschaltet. 5.24 müsste ich jetzt erst installieren  - ist zu weit weg.  :)
Und dann ist es wurst ob man sein Debian updated oder nicht, die eigene Perl Installation ist davon unbeeindruckt.

Ich muss das so machen, ich habe Arch und die drücken einem ja alle Nase lang was neues rein, da braucht man perlbrew schon wegen der Stabilität der eigenen Entwicklungsumgebung. Gilt aber prinzipiell für jede Distri.


Bei Perlbrew bekommt man momentan aber auch nix anderes als 5.24.4 mehr:

$ perlbrew available

  perl-5.31.10   
   perl-5.30.2   
   perl-5.28.2   
   perl-5.26.3   
  perl-5.26.3.tar.bz2   
   perl-5.24.4   
  perl-5.22.4.tar.bz2   
   perl-5.22.4   
  perl-5.20.3.tar.bz2   
   perl-5.20.3   
  perl-5.18.4.tar.bz2   
   perl-5.18.4   
   perl-5.16.3   
  perl-5.16.3.tar.bz2   
   perl-5.14.4   
  perl-5.14.4.tar.bz2   
  perl-5.12.5.tar.bz2   
   perl-5.12.5   
  perl-5.10.1.tar.bz2   
   perl-5.10.1   
  perl-5.8.9.tar.bz2   
    perl-5.8.9   
    perl-5.6.2   
  perl5.005_03   
  perl5.004_05   
  cperl-5.29.2   
  cperl-5.30.0   
  cperl-5.30.0-RC1   
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.