Schrift
[thread]12487[/thread]

Use of uninitialized value

Leser: 2


<< |< 1 2 >| >> 13 Einträge, 2 Seiten
~Br4inP4in~
 2008-09-13 15:11
#114589 #114589
User since
2007-06-13
28 Artikel
BenutzerIn
[default_avatar]
Hi.

Ich habe eine relativ simple Frage:
Ich programmiere oft mit dem CGI-Modul und muss hierbei oft Bedingungen wie
Code (perl): (dl )
if ($obj_cgi->param('order') eq 'name') {  }

stellen, wobei der parameter 'order' nicht zwingend existiert.
Dennoch möchte ich nicht auf strict und warnings verzichten,
weshalb sehr häufig der Fehler
Code: (dl )
Use of uninitialized value in string eq at ...

in meine Logs geschrieben wird.

Nun könnte ich wahrscheinlich diese Warnung deaktivieren oder
ich könnte jeden dieser Aufrufe in ein If-Statement packen, etwa so:
Code (perl): (dl )
1
2
3
4
if (defined($obj_cgi->param('order')))
{
    if ($obj_cgi->param('order') eq 'name') {  }
}


Das würde allerdings meinen Code um "einige" Zeilen bereichern...

Dennoch hoffe ich, dass es noch einen eleganteren Weg gibt?

Gruß, ~Br4inP4in~
MatthiasW
 2008-09-13 15:23
#114591 #114591
User since
2008-01-27
367 Artikel
BenutzerIn
[default_avatar]
Ich gehe mal von Perl 5.8 aus.

Du könntest ein or 0 an den zu prüfenden Parameterwert setzen:
Code (perl): (dl )
if ( $obj_cgi->param('order') or 0 eq 'name' ) { }


MfG
perl -E'*==*",s;;%ENV=~m,..$,,$&+42;e,$==f;$"++for+ab..an;@"=qw,u t,,print+chr;sub f{split}say"@{=} me"'
Struppi
 2008-09-13 15:38
#114592 #114592
User since
2006-02-17
628 Artikel
BenutzerIn
[Homepage]
user image
oder besser ein or '', da der Stringvergleich auf eine Zahl ebenfalls eine Warnung erzeugen sollte.
~Br4inP4in~
 2008-09-13 16:03
#114593 #114593
User since
2007-06-13
28 Artikel
BenutzerIn
[default_avatar]
Hey, wieder was gelernt :)
Das scheint wohl die einfachste Methode zu sein, kein logfile-flooding mehr ;)

Danke euch!
GwenDragon
 2008-09-13 16:06
#114595 #114595
User since
2005-01-17
14748 Artikel
Admin1
[Homepage]
user image
Code: (dl )
1
2
3
4
if ( defined($obj_cgi->param('order')) 
and ($obj_cgi->param('order') eq 'name') ) {
# code ...
}

ginge doch auch ;)
pq
 2008-09-13 16:07
#114596 #114596
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
leute, probiert das doch bitte einmal aus, bevor ihr postet.
1. ein 'or' hat zu geringe präzedenz, als dass man es hier verwenden könnte.
beweis:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
perl -wle'
my $order;
print "undef" if ($order or 0 eq "name");
$order = "";
print "empty string" if ($order or 0 eq "name");
$order = "name";
print "name" if ($order or 0 eq "name");
$order = "not name";
print "not name" if ($order or 0 eq "name");'
name
not name

es wird zuerst geprüft, ob $order true ist, und dann, ob 0 gleich "name" ist.
das *kann* nicht funktionieren. wie man sieht.

also: *wenn* dann || verwenden.

2. wenn man nun $var || '' oder $var || 0 benutzt, muss man ganz doll aufpassen,
es mag hier die schreibarbeit verkürzen, aber ich hab schon mal eine weile
gesucht, um einen bug zu finden, der durch so etwas entstanden ist. überall, wo
man $var || '' schreibt, wird die 0 automatisch zu '', und überall, wo man
$var || 0 schreibt, wird '' automatisch zu 0. das ist *hier* in diesem fall kein
problem, aber sobald das progrämmchen ein bisschen grösser wird, kann
es das werden. also wenn man soetwas benutzt, immer nachdenken, ob es
einen fall gibt, in dem die 0 oder der leere string auch ok wären.

3. @struppi: wieso soll $zahl eq "string" eine warnung ergeben? nur ein numerischer
vergleich erzeugt bei soetwas eine warnung.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
MatthiasW
 2008-09-13 16:09
#114597 #114597
User since
2008-01-27
367 Artikel
BenutzerIn
[default_avatar]
@Struppi, solch eine Warnung kann ich bei mir nicht erzeugen:
Code (perl): (dl )
1
2
3
4
5
6
7
8
#!/usr/bin/perl

use strict;
use warnings 'all';

my $a = undef;

print $a || 0 eq 'name' ? 1 : 0;

Gibt ohne Warnung 0 aus.

Allerdings sieht es bei einem Zahlenvergleich auf einen String wieder anders aus, da bekommt man die Meldung:
Code: (dl )
Argument ... isn't numeric in numeric eq (==) at ...

MfG
perl -E'*==*",s;;%ENV=~m,..$,,$&+42;e,$==f;$"++for+ab..an;@"=qw,u t,,print+chr;sub f{split}say"@{=} me"'
Struppi
 2008-09-13 16:14
#114598 #114598
User since
2006-02-17
628 Artikel
BenutzerIn
[Homepage]
user image
JaJa, schon gesehen, ich bevorzuge halt den Umweg über eine Variabel, bevor ich vergleiche und bei einem Stringvergleich nehme ich halt einen Leerstring als Defaultwert. Mir war aber tatsächlich nicht bekannt, dass es kein Problem ist zwei Zahlen mit eq/ne zu vergleichen.
MatthiasW
 2008-09-13 16:18
#114601 #114601
User since
2008-01-27
367 Artikel
BenutzerIn
[default_avatar]
@pq, danke hatte nur undef und 'name' getestet. In det Tat fehlen überall die Klammern um $irgendwas or 'irgendwas'

Mit Klammern funktioniert es jedoch einwandfrei:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/perl

use strict;
use warnings 'all';

my $a = undef;
print "1) \$a eq 'name'\n" if ($a or 0) eq 'name';

$a = 'name';
print "2) \$a eq 'name'\n" if ($a or 0) eq 'name';

$a = 'not name';
print "3) \$a eq 'name'\n" if ($a or 0) eq 'name';

MfG
perl -E'*==*",s;;%ENV=~m,..$,,$&+42;e,$==f;$"++for+ab..an;@"=qw,u t,,print+chr;sub f{split}say"@{=} me"'
pq
 2008-09-13 16:21
#114602 #114602
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
Struppi+2008-09-13 14:14:30--
JaJa, schon gesehen, ich bevorzuge halt den Umweg über eine Variabel, bevor ich vergleiche und bei einem Stringvergleich nehme ich halt einen Leerstring als Defaultwert.

der bug, den ich damals gesucht hatte, war eine art template-funktion:
Code (perl): (dl )
1
2
3
sub template {
    my $string = shift || '';
}

in meinem fall war aber durch die gegebenen umstände der parameter "0". was
eigentlich hätte gültig sein müssen. ich habe mich eine ganze weile gewundert, wo meine 0
hin verschwunden ist. wenn man an einem komplexen system arbeitet, dessen code man
(noch) nicht zu 100% kennt, dann kann man schon eine weile damit verbringen, die
schuldige stelle zu finden.

ich sag das deswegen so nachdrücklich, weil ich immer wieder auf solche fehler stosse.
natürlich habe ich auch selbst fehler gemacht, aber ich gewöhne mir bei solchen sachen
dann halt best practices an. $var || '' ist ein rotes tuch für mich. ich benutze es selbst durchaus
auch, aber eben (hoffentlich!) nur da, wo ich weiss, es ist ok.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
<< |< 1 2 >| >> 13 Einträge, 2 Seiten



View all threads created 2008-09-13 15:11.