Schrift
[thread]8127[/thread]

verwirrende aussagen auf perldoc.perl.org: bezogen auf defined



<< >> 5 Einträge, 1 Seite
legine
 2006-06-30 18:16
#67742 #67742
User since
2006-06-30
32 Artikel
BenutzerIn
[default_avatar]
Hallo,

Mein erster Beitrag hier ^^.

Ich habe ein verständnisproblem mit folgender Aussage aus der Perldocumentation bezüglich defined:
Quote
Note: Many folks tend to overuse defined, and then are surprised to discover that the number 0 and "" (the zero-length string) are, in fact, defined values. For example, if you say

Code: (dl )
"ab" =~ /a(.*)b/;


The pattern match succeeds, and $1 is defined, despite the fact that it matched "nothing". It didn't really fail to match anything. Rather, it matched something that happened to be zero characters long. This is all very above-board and honest. When a function returns an undefined value, it's an admission that it couldn't give you an honest answer. So you should use defined only when you're questioning the integrity of what you're trying to do. At other times, a simple comparison to 0 or "" is what you want.


Mein Problem ist nun:
Wenn ich nach einem failed matching ausschauhalten möchte, würde das defined, aber auf obigen fall auch anspringen, oder sehe ich das Falsch? (zumindest in meinen Beispiel würde ein defined genauso gut funktionieren wie ein ($var eq "").
Wenn ja warum dann der Aufstand um das defined. Ich verstehe das nicht so ganz. Habt ihr ne Idee was Jon Allen (nehme mal an das er das Geschrieben hat) damit aussagen will?

Grüße
Legine
Relais
 2006-06-30 21:19
#67743 #67743
User since
2003-08-06
2246 Artikel
ModeratorIn
[Homepage] [default_avatar]
Willkommen @Legine!

Ja, ich habe verstanden, worum es in der Perldoc geht.
Ich bin mir nicht ganz sicher, was Du mißverstanden hast, aber es geht so:
Das "Nichts", welches im Pattern Match gefunden wird, ist ein definiertes nichts. Mit defined() wirst Du es also nicht als Falsch erkennen.

Das bedeutet, wie es in der Einleitung schon heißt, daß Du mit defined() auf dem falschen Dampfer bist. Du kannst aber einen Leeren String immer noch mit einem anderen Leeren String vergleichen, ebenso wie die Zahl Null mit der Zahl null. Beispiel:
Code: (dl )
defined $1 and $1 ne ""


edit: noch besser ersetzt Du das .* vielleicht durch ein .+ - welches dann mindestens ein Zeichen matchen muß. Natürlich nur, wenn das für Deine Aufgabe in Frage kommt.

edit2: "Warum der Aufstand um das defined()? An dieser Stelle vermutlich, weil der Perldoc-Autor dieses Fettnäpfchen entweder öfters beobachtet hat, oder selber viel Zeit damit verbrachte, nehme ich mal an. defined() an sich ist vielerorts sehr hilfreich, wenn man es erst als Werkzeug schätzen gelernt hat, sollte man dann auch die Grenzen beachten.\n\n

<!--EDIT|Relais|1151688290-->
Erst denken, dann posten --
27. Deutscher Perl- u. Raku -Workshop (Termin wird noch gesucht) 2025 in München.

Winter is Coming
legine
 2006-06-30 22:44
#67744 #67744
User since
2006-06-30
32 Artikel
BenutzerIn
[default_avatar]
hehe danke.

Komisch.
Ich matche eine Zeile im folgenden Programm (wobei x irgendein inhalt ist.):
xxxxxxx xx xxxxxxx xxxxxxxxxxx xxxxx
---------------------------------------------------
xxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx
xxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx
xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx

So mein match sieht so aus
Code: (dl )
$zeile =~ /^\s+([a-zA-Z0-9]{0,16})\s+([a-zA-Z0-9]{0,8})\s+([a-zA-Z0-9]{0,16})\s+([a-zA-Z0-9]{0,8})/;


Klar die ersten 2 Zeilen Matchen nicht. Also exact der beschriebene Fall.

Komisch nur das die Zeile:
Code: (dl )
1
2
unless (defined ($Match[0])) {
...}

die unerwüschten Zeile herausfiltert und das wiederum führt zu mächtig viel verwirrung auf meiner Seite. (Notiz. die suchergebnisse aus $1 werden in $Match[0] kopiert weil ich das array später noch brauche)

Nur so als anmerkung, klar benutze ich die zeile ($1 eq "") als entscheidungskriterium weil ich es besser lesbar finde.
Dubu
 2006-07-01 02:23
#67745 #67745
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Vorsicht, Vorsicht!

Man sollte immer auf den Match selber testen, nicht auf $1 etc.
Warum? Weil die Variablen $1, $2 etc. bei einem neuen Match nicht automatisch auf undef zurückgesetzt werden. Wenn der Match greift, bekommen sie einen neuen wert, aber wenn er nicht greift, behalten sie ihren alten Wert!

Code: (dl )
1
2
3
4
5
6
7
8
9
10
### FALSCH
$zeile =~ /...(...).../;
if ($1 ne "") {
   # hier steht evtl. etwas altes in $1
}

### RICHTIG
if ($zeile =~ /...(...).../) {
  # jetzt kann man $1 etc. verwenden
}
legine
 2006-07-02 13:30
#67746 #67746
User since
2006-06-30
32 Artikel
BenutzerIn
[default_avatar]
cool.
wusste ich gar nicht :D
Werde das gleich mal korrigieren.
<< >> 5 Einträge, 1 Seite



View all threads created 2006-06-30 18:16.