Toon posts:

[Perl]Gebruik van strict

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb weereens ruzie met het gebruik van strict.
Het probleem van de benedenstaande code is, dat op de regel van de print, de variable $newline geen waarde heeft. (terwijl die wel wordt gereturned en correct wordt geinterpreteerd door de while-lus)

Iemand een idee hoe ik binnen die scope van de de while-lus, de $newline ook een waarde nog/weer kan hebben?
my $newline = shift(@_) boven de print werkt bijvoorbeeld niet.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/perl

use strict;

while (&readnewline ne "close")
{
    print $newline;
}


sub readnewline
{
    my $newline = (<INFILE>);
    return ($newline);
}

[ Voor 1% gewijzigd door Verwijderd op 29-08-2006 10:26 . Reden: syntaxis-dingetje ]


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 22-01 23:51

NMe

Quia Ego Sic Dico.

Niet geremd door enige Perl-kennis zeg ik: een functie maken die een waarde returnt en die waarde opslaan in een tussenvariabele die je kan gebruiken.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • chaotik
  • Registratie: Januari 2001
  • Laatst online: 10-08-2025
Zoals -NMe- zei, zou je idd buiten je while loop en sub definitie de $newline variabele kunnen declareren. Verder is het misschien handig om te vertellen in welke context je deze code gebruikt en wat je er mee wilt bereiken.

Ik krijg een beetje het idee dat je een (text)bestand regel voor regel wilt uitlezen. Dat kan in Perl namelijk een stuk makkelijker op deze manier:
code:
1
2
3
4
while ( my $newline = <INFILE> )
{
    print $newline;
}

  • Grum
  • Registratie: Juni 2001
  • Niet online
Perl:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/perl

use strict;

while (&readnewline ne "close")    #1
{
    print $newline;
}


sub readnewline
{
    my $newline = (<INFILE>); #2
    return ($newline); #3
}


1/ daar staat: while(1) - wat er ook gebeuren zal je returnvalue van readnewline zal _NOOIT_ "close" zijn - het dichtste bij wat je zal komen is "close" met een newline erachter (unix/windows/mac)
2/ waarom gebruik je hier haakjes? Waar open je 'INFILE' ?
3/ waarom gebruik je hier haakjes?

Ben je je bewust van de verschillende contexten die perl kan hebben? Void, scalar en list context?

Een alternatieve manier van opschrijven (kort en bondig) van wat jij wilde doen:
Perl:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/perl
use strict;
use warnings;

open INFILE, .....;

while (<INFILE>) {
    last unless m/^close$/;

    print;
}

# of iets in de trant van:
# while (($_ = <INFILE>) !~ m/^close$/) { print }
# of
# m/^close$/ ? last : print for (<INFILE>);


En zoals met alles in Perl, TIMTOWTDI (The is more than one way to do it).

  • TrailBlazer
  • Registratie: Oktober 2000
  • Laatst online: 07-02 09:48

TrailBlazer

Karnemelk FTW

code:
1
2
3
4
5
6
7
8
9
#!/usr/bin/perl
use strict;
die "to little arguments\n" unless defined $ARGV[0];
open (FILE,$ARGV[0]) || die "unable to open file $ARGV[0]\n";
while (<FILE>) {

last if /close/;
print;
}

dit is denk ik wel de meest simpele versie redelijk foolproof en zelfs geen extra variabelen nodig

  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

Je vraag is je antwoord.
Je wil *binnen de scope* van de while lus die variable hebben. Scopes zijn de blokken tussen { en }.
Zoals je vrij duidelijk ziet, staat sub readline {} niet *binnen de scope* van while (...) {}.

code:
1
2
3
4
5
6
7
8
9
10
use strict;
while ( (my $newline = &readnewline) ne "close" ) {
    print $newline;
}


sub readnewline {
    my $newline = <INFILE>;
    return $newline;
}



EDIT: bovendien zal dit nooit werken, omdat je de linebreak nooit uit je regels verwijderd.
Het werkt dus alleen als "close" op de allerlaatste regel van je bestand staat - zonder linebreaks erachter.
En als het er niet staat krijg je alsnog een error (je probeert dan nml uit een bestand te lezen tot voorbij EOF!)
Daarom deze update:

code:
1
2
3
4
5
sub readnewline {
    my $newline = <INFILE>;
    chomp $newline;
    return $newline;
}

[ Voor 35% gewijzigd door muba op 30-08-2006 01:04 ]

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 14-02 19:13
Hey Grum, wtf doe jij hier weer? :P
Grum schreef op dinsdag 29 augustus 2006 @ 21:49:
1/ daar staat: while(1) - wat er ook gebeuren zal je returnvalue van readnewline zal _NOOIT_ "close" zijn - het dichtste bij wat je zal komen is "close" met een newline erachter (unix/windows/mac)
Oh ja?
code:
1
echo -n close | perl -e 'print "woei\n" if <> eq "close"'

(Mierenneuken, ik weet het, maar het is dus nooit nooit. De reden dat Perl die newline character laat staan is nu juist precies dat je kunt onderscheiden of een bestand met of zonder newline character eindigt - als 'ie er altijd staat hadden ze 'm wel kunnen chompen.)

Verder zijn er natuurlijk 'tig manieren om het op te lossen, maar het directe antwoord op de vraag in de TS is: declareer die variabele dan gewoon!
Perl:
1
2
3
while ((my $line = &readnewline) ne "close") {
    print $line;
}


Met 'my' declareer je een soort locale variabale, dus het is logisch dat de $newline uit &readnewline niet beschikbaar is in de aanroepende context. Je kunt er ook wel een globale variabele van maken, maar dat is juist de rommel die niet de bedoeling is in strict mode.

[ Voor 12% gewijzigd door Soultaker op 30-08-2006 01:16 ]


  • Grum
  • Registratie: Juni 2001
  • Niet online
Soultaker schreef op woensdag 30 augustus 2006 @ 01:14:
Hey Grum, wtf doe jij hier weer? :P

[...]

Oh ja?
code:
1
echo -n close | perl -e 'print "woei\n" if <> eq "close"'

(Mierenneuken, ik weet het, maar het is dus nooit nooit. De reden dat Perl die newline character laat staan is nu juist precies dat je kunt onderscheiden of een bestand met of zonder newline character eindigt - als 'ie er altijd staat hadden ze 'm wel kunnen chompen.)
Helaas heb je gelijk ;) en ik idle gewoon.

Verwijderd

Topicstarter
Bedankt voor alle reacties.
Uiteraard stond er veel meer code omheen. En ik haalde deze kromme actie niet uit omdat ik niet op de hoogte was van zoiets als wat chaotik voorstelde, maar ik heb het alleen zo gepost om op een simpele manier mijn probleem te tonen. (even het probleem isoleren, zeg maar. Daarom heb ik de topic ook "Gebruik van strict" genoemd :))
Ook ben ik bekend met dat je een file eerst moet openen voor je 'm kunt inlezen, en dat er newlines in een textfile kunnen staan.
Anyways, antwoord is mij duidelijk en daar gaat het tenslotte allemaal om. :)
Nogmaals dank!

[ Voor 5% gewijzigd door Verwijderd op 31-08-2006 10:18 ]

Pagina: 1