Ich versteh die Logik hierbei nicht
xNeTworKx
- perl
0 Frank Schönmann0 xNeTworKx0 Erik0 Klaus Mock0 xNeTworKx
0 klaus Mock
Hello,
kleines Problem:
Ich frage das Verzeichnis nach der Datei datenbank.txt ab, falls diese nicht gefunden wird, wird das Array @daten logischerweise nicht mit Daten gefüllt und ist somit leer.
So die Datei datenbank.txt existiert jetzt zur Probe nicht, und ich will mir zur Probe den Text "Leer" ausgeben lassen, falls @daten leer ist, aber das tut er nicht. Wenn ich jetzt auf if (@daten ne '') gehe, gibt er mit "Leer" aus. Kann mir jemand sagen warum ?
#!C:\Perl\bin\Perl.exe -w
use CGI;
$query = new CGI;
@daten = '';
$verzeichnis = ".";
print $query->header;
opendir(DIR, "$verzeichnis") or die "Verzeichnis kann nicht geoeffnet werden : $!\n";
while ($file = readdir(DIR)) {
if ($file =~ /datenbank.txt/) {
open(FILE,"datenbank.txt") or die "Kann Datenbank nicht oeffnen : $!\n";
@daten = <FILE>;
}
}
if (@daten eq '') {
print 'Leer!';
}
hi!
if (@daten eq '') {
Array ^^^^^^ ^^ String
Was glaubst du, was passiert, wenn du ein Array mit einem String
vergleichst?
bye, Frank!
Hallo, danke für eure Hilfe,
Ich habs jetzt folgendermaßen gemacht:
#!C:/Perl/bin/Perl.exe -w
use CGI;
$query = new CGI;
$verzeichnis = ".";
print $query->header;
opendir(DIR, "$verzeichnis") or die "Verzeichnis kann nicht geoeffnet werden : $!\n";
while ($file = readdir(DIR)) {
if ($file =~ /^datenbank.txt$/) {
open(FILE,"$verzeichnis/datenbank.txt") or die "Kann Datenbank nicht oeffnen : $!\n";
@daten = <FILE>;
}
}
$ae = @daten;
if ($ae == 0) {
print "Leer!\n";
}
So gehts zwar, aber ich versteh das mit @daten eq '' oder "" noch nicht ganz.
Wie kann ich eigentlich "Falls Array leer ist" sagen? if (@array ???
So gehts zwar, aber ich versteh das mit @daten eq '' oder "" noch nicht ganz.
Wie kann ich eigentlich "Falls Array leer ist" sagen? if (@array ???
if (scalar(@array)==0) oder if ((@array+0))==0).
HTH
Erik
Ok verstanden, danke =)
Hi!
if (scalar(@array)==0) oder if ((@array+0))==0).
Oder einfach
if (@array == 0)
Da die Vergleichsoperatoren sowieso nur auf Skalaren arbeiten, bringt == das @array schon in skalaren Kontext, daher ist das 'scalar' redundant.
So long
Hallo Calocybe,
if (scalar(@array)==0) oder if ((@array+0))==0).
Oder einfach
if (@array == 0)
Da die Vergleichsoperatoren sowieso nur auf Skalaren arbeiten, bringt == das @array schon in skalaren Kontext, daher ist das 'scalar' redundant.
Noch viel einfacher und voll funktional wäre:
if(@array) {...} oder if (!@array) {...}
Ein Array ist nämlich afaik wahr, sobald es wenigstens ein Elment enthält.
Gruß Alex
--
http://www.google.de/search?hl=de&safe=off&q=Rechtschreibung+Standart
Hallo,
Ich habs jetzt folgendermaßen gemacht:
[...]
So gehts zwar,
Hier nochmals mein Vorschlag:
<code>
#!C:/Perl/bin/Perl.exe -w
use strict;
use CGI;
my $query = new CGI;
my $verzeichnis = '.'; # wobei noch anzmerken ist, das das aktuelle Verzeichnis nicht wirklich definiert ist
my @daten;
print $query->header;
if(-e "$verzeichnis/datenbank.txt")
{
open(FILE,"$verzeichnis/datenbank.txt") or die "Kann Datenbank nicht oeffnen : $!\n";
@daten = <FILE>;
close FILE or die "Kann Datenbank nicht schliessen : $!\n";
}
if( scalar @daten == 0)
{
print 'Datei nicht gefunden oder es steht nix drin';
}
</code>
aber ich versteh das mit @daten eq '' oder "" noch nicht ganz.
Weil Du hier ein Array (anscheinend die Anzahl der Arrayelemente) mit einem Text vergleichst. Und da ist die Wahrscheinlichkeit ziemlich groß, daß nicht das gewünschte Ergebnis erzielt wird.
Wie kann ich eigentlich "Falls Array leer ist" sagen? if (@array ??
( scalar @daten == 0)
oder (inzwischen etwas verpönt)
($#daten == -1)
Grüße
Klaus
Hi, ok ich hab jetzt dein Script genommen
Das versteh ich aber noch nicht so ganz
my $verzeichnis = '.'; # wobei noch anzmerken ist, das das aktuelle Verzeichnis nicht wirklich definiert ist
wieso eigentlich nicht ?
und zu use strict : Ich hab jetzt mal das use strict beibehalten, aber ich habs nie verwendet weil ich nie weis wann man my setzen muss, immer nur am Anfang ? Ich bild mir ein ich hab mal wo gesehen, daß mitten im Script auch ein my vorgekommen is, oder nicht ?
Hallo,
my $verzeichnis = '.'; # wobei noch anzmerken ist, das das aktuelle Verzeichnis nicht wirklich definiert ist
wieso eigentlich nicht ?
Weil im Webumfeld es nicht sicher ist, daß das aktuelle Verzeichnis beim Scriptaufruf auch dort ist, wo Du es erwartest.
und zu use strict : Ich hab jetzt mal das use strict beibehalten, aber ich habs nie verwendet weil ich nie weis wann man my setzen muss, immer nur am Anfang ? Ich bild mir ein ich hab mal wo gesehen, daß mitten im Script auch ein my vorgekommen is, oder nicht ?
Kurze Antwort:
Du kannst my verwenden, wann Du willst, nicht nur am Anfang. In jedem Fall mußt Du, es in Verbindung mit 'use script', vor, oder spätestens bei, der ersten Verwendung der Variable benutzen.
Längere Antwort:
my bestimmt eigentlich den Gültigkeitsbereich einer Variable. Wenn Du eine Variable mittels my innerhalb eines Blocks deklarierst, dann ist diese Variable auch nur innerhalb dieses Blocks 'vorhanden', also gültig).
eigentlich kannst Du jederzeit eine neue Variable mit my einführen, sie gilt eben bis zum Ende des Blocks.
Wird eine Variable nicht innerhalb eines Blocks definiert, dann gilt sie ab dem Zeitpunkt der Definition innerhalb der restlichen Scriptdatei, aber nur innerhalb dieser Scriptdatei. Das ist vor allem bei der Modulentwicklung wichtig.
Einen Block erkennst Du an den geschwungenen Klammern, welche Anweisungen einfassen, nicht zu verwechseln mit den Klammern, die Du bei Hashes verwendest.
Beispiel:
#!/usr/bin/perl -w
use strict;
my $zeile;
my $dateiname = '/wo/auch/immer/wasauchimmer.txt';
open(IN,$dateiname);
while($zeile = <IN>)
{ # hier beginnt ein Block
chomp $zeile; # auch innerhalb dieses Blocks ist $zeile das gleiche wie außerhalb
my(@werte) = split(';',$zeile); # ab hier ist @werte deklariert, und gilt bis zum Ende des Blocks
# weitere Anweisungen
} # hier endet der Block
Hilfreich ist my unter anderem auch, weil Du in einem Block Variablen verwenden kannst, unabhängig davon, ob sie außerhalb schon verwendet werden oder nicht.
Beispiel:
my $zeile = 'wasauchimmer';
print $zeile; # gibt 'wasauchimmer' aus, da $zeile so belegt wurde
if(-e $dateiname)
{
open(IN,$dateiname);
my $zeile; # hier wird $zeile für den Block neu definiert
print $zeile; # gibt einen leeren String aus, da $zeile in diesem Block noch leer ist
while($zeile = <IN>)
{
print $zeile; # gibt den inhalt der Datei zeilenweise aus
}
}
print $zeile;
Das ist vor allem beim Schreiben von Funktionen ein äußerst hilfreiches Verhalten.
Du siehst, my ist nicht nur zur Vermeidung von Fehlermeldungen bei 'use strict' interessant, sondern auch für viele andere interessante Anwendungsfälle.
Seit Perl 5.6 gibt es auch 'our', wodurch es auch möglich wurde, wirklich globale Variablen zu deklarieren. Bei frühere Versionen von Perl mußte man sich entscheiden, ob man 'use strict', oder globale Variablen verwenden wollte.
In den meisten Fällen sind globale Variablen zwar unsauber, aber ab und zu kann man damit eine Sache dann doch eleganter lösen, unabhängig davon, was Puristen davon halten.
Es gibt da noch eine Funktionalität, deren Verhalten zwar 'my' nicht unähnlich ist, aber intern vollkommen anders arbeitet. Ich rede hier von 'local'. Aber Du solltest Dich nicht mehr damit abgeben, da es IMHO noch ein Relikt aus vergangenen Tagen ist. Ich wollte es nur der Vollständigkeit halber erwähnt haben.
Jetzt hoffe ich, daß ich etwas Licht in die Sache gebracht habe, ohne vollständig zu verwirren.
Grüße
Klaus
Hi,
danke für die Info, ich glaub jetzt kapier ichs =)
Hallo,
#!C:\Perl\bin\Perl.exe -w
use CGI;
Und ich dachte, 'use strict' hat sich inzwischen rumgesprochen;-)
$query = new CGI;
@daten = '';
Dir ist hoffentlich klar, daß Du damit kein leeres Array erzeugts, sondern eines in dem im ersten Arrayelement ein leerer String steht.
$verzeichnis = ".";
print $query->header;
opendir(DIR, "$verzeichnis") or die "Verzeichnis kann nicht geoeffnet werden : $!\n";
while ($file = readdir(DIR)) {
if ($file =~ /datenbank.txt/) {
open(FILE,"datenbank.txt") or die "Kann Datenbank nicht oeffnen : $!\n";
@daten = <FILE>;
}
}
Hier drei Anmerkungen von mir:
1.) Du kannst die Existenz einer Datei auch mit
if(-e $datei)
{
# mach was mit der Datei
}
else
{
# hmm, nix gefunden
}
überprüfen. Abgesehen davon, daß es einfach zu schreiben ist, ist es auch wesentlich performanter.
2.) wenn Du schon $verzeichnis durchsuchst, solltest Du dann auch
open(FILE,"$verzeichnis/$file") or die "blablabla";
für den gewünschten File machen.
Das macht zwar im aktuellen Zustand Deines Scripts keinen Unterschied, aber irgendwann änderst Du vielleicht die Zeile
$verzeichnis = '.';
auf
$verzeichnis = '/and/now/to/something/complete/different';
und suchst dann bis zur Verzweiflung, warums das Script plötzlich nicht mehr funktioniert.
3.)
if ($file =~ /datenbank.txt/) {
open(FILE,"datenbank.txt") or die "Kann Datenbank nicht oeffnen : $!\n";
Ist eigentlich auch 'suboptimal', da das Matching auch auf Dateinamen wie 'kopie von datenbank.txt', 'datenbank2txt' oder 'was auch immer fuer eine datenbank,txt sollte auf jeden fall dabei sein' anspringt.
wenn dann
if ($file =~ /^datenbank.txt$/) {
if (@daten eq '') {
print 'Leer!';
}
Hmm, was da genau passiert, ist mir auch schleierhaft. Wird @daten in einen String gejoint (anscheinend nicht) oder implizit ein 'scalar @daten' ausgeführt, oder irgendwas anderes. Weiß auch nicht. Unsicher ist das allemal.
Hier zwei mögliche Lösungen
unless(-e "$verzeichnis/datenbank.txt")
{
print 'Leer!';
}
else
{
# einlesen und verarbeiten der Daten
}
(Das unless deshalb, um elegant den codemäßig kürzeren Teil eventuell nach vorne zu bringen, was die Lesbarkeit des Scripts erhöht.)
oder
my @daten;
if(scalar @daten ==0)
{
print 'Leer!';
}
Grüße
Klaus