Thread erstes Zeichen - prüfen (15 answers)
Opened by jan999 at 2010-01-04 15:43

sid burn
 2010-01-04 16:31
#130002 #130002
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
In "@_" werden nur die Subroutinen Parameter abgelegt sonst nichts.

Bei $1 ist das noch etwas anderes. $1, $2, $3 etc. sind globale Variablen. Daher sie sind über das komplette Programm gültig und werden mit jeder ausführung einer Regex neu gesetzt.

Daher wenn man eine Regex nutzt und eine Subroutine aufruft die ebenfalls eine Regex ausführt überschreibt diese $1 sofern die Regex in dieser Subroutine erfolgreich war.

Daher sollte man wenn man eine Regex angewendet hat und die Werte in $1, $2, ... benötigt diese werten immer Variablen zuweisen direkt nach dem ausführen der regex.

Mit "@_" gibt es da nicht so die Probleme da @_ für jede subroutine lexikalisch ist, allerdiengs sollte man auch hier am anfang die werte aus @_ lesen und bennanten veriablen zu weisen. Einmal da es leserlicher ist, zum anderen ändert man mit $_[0] etc. das Original.

Solche Probleme gibt es generell mit globalen Variablen weswegen man auch keine globalen variablen nutzen sollte, aber Perl hat ja nunmal einige vorgegeben.

Gleiche Problematik kann man auch mit $_ machen. Deswegen sollte man zum Beispiel auch
Code: (dl )
while ( my $line = <$h> ) { ...}
nutzen.

Ebenfalls möglich ist auch ein vorheriges lokalisieren mit "local". Seit Perl 5.10 kann man auch $_ mit "my" lokalisieren bzw daraus eine lexikalische variable machen.

Was auch noch auftreten kann ist Fehlerbehanlung mit $@. Zum Beispiel einen fehler den ich mal hatte.

Code (perl): (dl )
1
2
3
4
5
6
7
8
if ( $@ ) {
  warn "Fehler...\n";
  redo();
  
  if ( $@->isa('ErrorX') ) {
    warn "zusätzlich tue das..\n";
  }
}


"$@" wird bei jedem aufruf von eval {} wieder gelöscht. Und wenn ein Fehler aufgetreten war hatte ich die aktuelle Aktion rückgängig gemacht, und dann getestet welcher Fehler aufgetreten war um dann noch etwas spezielles zu tun.

Da aber in redo() ebenfalls ein eval {} war wurde somit $@ wieder gelöscht, und da im diesen eval {} kein Fehler vorkam war $@ danach leer gewesen und die spezielle aktion danach fehlte. Natürlich hatte ich noch vorher ein check mit blessed ob es ein Objekt war bevor ich ->isa() aufgerufen habe sonst würde der Code sogar eventuell mit einer fehlermedung abbrechen wenn kein Objekt zurück kommt.

Daher generell immer zu empfehlen. Keine globalen Variablen nutzen oder vorher lokalisieren. Aber eigentlich gibt es im großen nur drei Fälle.

Fehler mit "$_". Hier versuche ich generell $_ zu vermeiden und weise immer alles Variablen zu.

Regexe mit $1, $2 etc. hier sollte man Werte nach einem Match immer sofort zuweisen.

Und beim Problem mit $@ sollte man zumindest Try::Tiny nutzen dass eine lokalisierung übernimmt oder sogar noch besser TryCatch. Letzteres ist Klasse wenn man sowieso schon z.B. mit Moose arbeitet.
Last edited: 2010-01-04 16:35:21 +0100 (CET)
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de

View full thread erstes Zeichen - prüfen