Bekijk Volledige Versie : Perl: Probleem bij manipuleren for-lus
Hallo,
Ik heb een probleem waarbij ik de oorzaak denk gevonden te hebben:
Ik doorloop mijn for-lus met de variabele $i.
In de lus wil ik $i aanpassen, maar dit blijkt geen invloed te hebben op de
waarde $i die het aantal loops in de forlus bijhoudt.
Heeft iemand enig idee als dit wel kan ? of een andere manier ?
De bedoeling is om een aantal foto's die in een map te zitten in te lezen en
deze in een tabel in 3 kolommen weer te geven.
mvg,
Ruben
print qq(<table class="content" width="100%" border="0" align="center">);
print qq(<tr>);
for $i (2..$#bestanden) {
print qq(<td><img src="$map/$bestanden[$i]" width="150"></td>);
controle();
$i+=1;
print qq(<td><img src="$map/$bestanden[$i]" width="150"></td>);
controle();
$i+=1;
print qq(<td><img src="$map/$bestanden[$i]" width="150"></td>);
controle();
$i+=1;
print qq(</tr><tr>);
}
print qq(</table>);
sub controle(){
if ($#bestanden == $i) {
last;
print qq(</tr>);
}
}
"RG" <ruben@tochniet.com> wrote in message
news:DQV2a.49067$Jd.6015@afrodite.telenet-ops.be...
> for $i (2..$#bestanden) {
> }
>
Zo werkt for() niet, je moet namenlijk wel zeggen hoelang die lus moet lopen
enzo, dit is de juiste syntax:
for($i=0;$i<10;$i++) {
print "$i\n";
}
On Thu, 13 Feb 2003 23:26:27 GMT,
"RG" <ruben@tochniet.com> wrote..
> for $i (2..$#bestanden) {
my ($i, $bestand)
foreach $bestand (2..$#bestanden) {
...
Ik denk dat dit beter gaat. En dan heb je je handen vrij met $i.
--
Hi! I'm a UNIX .signature virus!
Copy me into your ~/.signature to help me spread..
Rene Pijlman
14/02/03, 00:45
Hans:
>foreach $bestand (2..$#bestanden) {
Ik zit in een Python-periode en bij elk stukje Perl-code dat ik
tegenkom word ik gesterkt in die keuze. Ik heb hier lang en diep
over nagedacht, maar ik heb echt geen flauw idee wat
bovenstaande code zou kunnen betekenen, terwijl ik vroeger toch
behoorlijk Perl geprogrammeerd heb.
Enfin, niemand heeft natuurlijk iets aan deze mededeling, maar
ik wilde het toch even gezegd hebben.
--
René Pijlman
Wat wil jij leren? http://www.leren.nl
On Fri, 14 Feb 2003 00:44:22 +0100,
Rene Pijlman <reageer.in@de.nieuwsgroep> wrote..
> ... maar ik heb echt geen flauw idee wat bovenstaande code
> zou kunnen betekenen ...
Ik moet bekennen dat ik ook behoorlijk stoned ben :-)
--
Hi! I'm a UNIX .signature virus!
Copy me into your ~/.signature to help me spread..
Rene Pijlman <reageer.in@de.nieuwsgroep>:
> Hans:
>>foreach $bestand (2..$#bestanden) {
>
> Ik zit in een Python-periode en bij elk stukje Perl-code dat ik tegenkom
> word ik gesterkt in die keuze. Ik heb hier lang en diep over nagedacht,
> maar ik heb echt geen flauw idee wat bovenstaande code zou kunnen
> betekenen, terwijl ik vroeger toch behoorlijk Perl geprogrammeerd heb.
Elke Unix-persoon met een beetje shellkennis zou het anders zo zien :)
--
robert
RG <ruben@tochniet.com>:
> for $i (2..$#bestanden) {
> print qq(<td><img src="$map/$bestanden[$i]" width="150"></td>);
> controle();
> $i+=1;
> ...
> }
>
> sub controle(){
> if ($#bestanden == $i) {
> last;
Dit gaat niet werken; 'last' is alleen van toepassing in de huidige scope,
en dat is de functie 'controle' (en dus niet je loop). Daarnaast is het
netter om $i (en eigenlijk ook $bestanden) als argument mee te geven in
plaats van er een globale variabele van te gebruiken.
Aldus:
sub controle
{
my $i = shift;
return ($#bestanden == $i);
}
En in je lus:
if (controle($i))
{
print "</tr>";
last;
}
Je zit nog wel met het feit dat je $i++ in die vorm van het for-statement
niet kunt gebruiken. Je moet dus de andere vorm inzetten:
for (my $i = 0; $i < $#bestanden; $i++)
{
...
}
Je weet overigens dat $#bestanden niet het aantal elementen in je array
teruggeeft, maar de index van het laatste element? (wat dus over het
algemeen een lager ligt dan het aantal elementen)
--
robert
"Rene Pijlman" <reageer.in@de.nieuwsgroep> schreef in bericht
news:5abo4vo1u679goeo51i0rb03ve72fris3k@4ax.com...
> Hans:
> >foreach $bestand (2..$#bestanden) {
>
> Ik zit in een Python-periode en bij elk stukje Perl-code dat ik
> tegenkom word ik gesterkt in die keuze. Ik heb hier lang en diep
> over nagedacht, maar ik heb echt geen flauw idee wat
> bovenstaande code zou kunnen betekenen, terwijl ik vroeger toch
> behoorlijk Perl geprogrammeerd heb.
>
> Enfin, niemand heeft natuurlijk iets aan deze mededeling, maar
> ik wilde het toch even gezegd hebben.
Mijn probleem is intussen opgelost door het op een andere manier te doen,
Maar ik zal even uitleggen wat dit doet:
de array bestanden bevat de inhoud van een map
element 0 en element 1 zijn de puntjes "." en ".."
Daarom dat ik begon vanaf 2 te tellen.
"robert" <robert+nl.internet.www.server-side@usenet-h.allyourbass.org>
schreef in bericht news:slrnb4pc0o.6s4.robert@home.allyourbass.org...
> RG <ruben@tochniet.com>:
> > for $i (2..$#bestanden) {
> > print qq(<td><img src="$map/$bestanden[$i]" width="150"></td>);
> > controle();
> > $i+=1;
> > ...
> > }
> >
> > sub controle(){
> > if ($#bestanden == $i) {
> > last;
>
> Dit gaat niet werken; 'last' is alleen van toepassing in de huidige scope,
> en dat is de functie 'controle' (en dus niet je loop). Daarnaast is het
> netter om $i (en eigenlijk ook $bestanden) als argument mee te geven in
> plaats van er een globale variabele van te gebruiken.
>
> Aldus:
> sub controle
> {
> my $i = shift;
>
> return ($#bestanden == $i);
> }
>
> En in je lus:
>
> if (controle($i))
> {
> print "</tr>";
> last;
> }
>
> Je zit nog wel met het feit dat je $i++ in die vorm van het for-statement
> niet kunt gebruiken. Je moet dus de andere vorm inzetten:
>
> for (my $i = 0; $i < $#bestanden; $i++)
> {
> ...
> }
>
> Je weet overigens dat $#bestanden niet het aantal elementen in je array
> teruggeeft, maar de index van het laatste element? (wat dus over het
> algemeen een lager ligt dan het aantal elementen)
Bedankt voor je uitleg, probleem is opgelost, en dat laatste wist ik (een
van de weinige dingen dak wist :) )
mvg,
Ruben
Ik probeer in perl altijd for loops met tellers te vermijden (it's soooo c!)
en de iterator 'foreach' te gebruiken, cleaner. In plaats van met de
waarden van variabelen te manipuleren, test ik liever condities. De modulus
operator % is uitermate geschikt voor 'ieder n-voud' te testen. Het geeft de
rest van een deling.
(Kijk een keer op pagina 101 van het Camel boek (2e druk) voor vegelijking
for loop en foreach).
Ongewenste array elementen voor de loop verwijderen, dan blijft de loop code
cleaner .
___________________
pop @bestanden; #weg met laatste
shift @bestanden; # idem eerste
print '<table><tr>';
foreach $bestand (@bestanden) {
print qq(<td><img src="$map/$bestand" width="150"></td>);
$index++;
print '</tr><tr>' if ($index % 3 == 0); # modulus
}
print '</tr></table>';
___________________
Clean genoeg voor Python lovers, dunkt me :-)
~henq
ps: iets korter, maar iets cryptischer:
foreach (@bestanden) {
print qq(<td><img src="$map/$_" width="150"></td>);
print '</tr><tr>' if ($index++ % 3 == 0); # modulus
}
pps: nog een variant, met next, ook mooi:
foreach (@bestanden) {
print qq(<td><img src="$map/$_" width="150"></td>);
next if ($index++ % 3 == 0); # modulus
print '</tr><tr>' ;
}
"RG" <ruben@tochniet.com> schreef in bericht
news:DQV2a.49067$Jd.6015@afrodite.telenet-ops.be...
> Hallo,
>
> Ik heb een probleem waarbij ik de oorzaak denk gevonden te hebben:
>
> Ik doorloop mijn for-lus met de variabele $i.
> In de lus wil ik $i aanpassen, maar dit blijkt geen invloed te hebben op
de
> waarde $i die het aantal loops in de forlus bijhoudt.
>
> Heeft iemand enig idee als dit wel kan ? of een andere manier ?
>
> De bedoeling is om een aantal foto's die in een map te zitten in te lezen
en
> deze in een tabel in 3 kolommen weer te geven.
>
>
> mvg,
> Ruben
>
>
>
>
>
> print qq(<table class="content" width="100%" border="0" align="center">);
>
> print qq(<tr>);
>
> for $i (2..$#bestanden) {
> print qq(<td><img src="$map/$bestanden[$i]" width="150"></td>);
> controle();
> $i+=1;
> print qq(<td><img src="$map/$bestanden[$i]" width="150"></td>);
> controle();
> $i+=1;
> print qq(<td><img src="$map/$bestanden[$i]" width="150"></td>);
> controle();
> $i+=1;
>
> print qq(</tr><tr>);
>
>
> }
>
>
> print qq(</table>);
>
>
> sub controle(){
> if ($#bestanden == $i) {
> last;
> print qq(</tr>);
> }
> }
>
>