Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]11375[/thread]

Frage zur for-Schleife

Leser: 1


<< |< 1 2 >| >> 15 Einträge, 2 Seiten
Gast Gast
 2008-02-27 14:01
#106424 #106424
Hallo liebe Leute,

ich muss euch heute leider auch mit einer Anfängerfrage belästigen!
Folgendes Programm liegt mir vor:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/perl -w
my @array=(1,2,4,8,16,32,64,128);
my @wert_1=grep {
    my $a=$array[$_];
    my $sum;
    $sum+=$_ for split //, $a;
    print "\$sum=$sum\n";
    $sum %2;
  }
  0..$#array;

print "@wert_1\n";
my @wert_2=@array[@wert_1];
print "@wert_2\n";



Die erste Print-Anweisung gibt mir nacheinander 1,2,4,8,7,5,10,11 aus (wegen split-Befehl und anschl. Addition der einzelnen Zahlen)

Die zweite Print-Anweisung gibt mir 0 4 5 7 aus. Leuchtet mir auch noch ein, da für hier die Bedingung %2 für grep greift und sie o. g. Werte in @wert schreibt.

Die dritte Bedingung gibt 1 16 32 128 aus. Das sind die Werte an den Positionen 0 4 5 7 vom Array @array.

Also soweit komme ich gut zurecht. Mein Problem ist allerdings die for-Anweisung in Zeile 6. Ich kenne sie nur so, dass man in runden Klammern den Initialisierungsteil, Bedingungsteil und Re-Initialisierungsteil schreibt und anschließend in geschweiften Klammern den Anweisungsblock.
Nur speziell der Anweisungsblock fehlt doch hier, oder etwa nicht?? Ich komme mit der Schreibweise nicht so ganz klar!

Wäre nett, wenn mir einer genau erklären könnte wie ich die Zeile 6 verstehen soll.

Vielen Dank für eure Bemühungen,

Michael

/----
Modedit Gwendragon:
Code in Perl-Tags gestellt und lesbar eingerückt
----
renee
 2008-02-27 14:16
#106425 #106425
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
$sum+=$_ for split //, $a; entspricht
Code: (dl )
1
2
3
for( split //, $a ){
$sum += $_;
}


Hier wird nicht über einen Index iteriert wie bei
Code: (dl )
1
2
my @array = split //, $a;
for( my $i = 0; $i <= $#array; $i++ ){ }

sondern direkt über die Elemente.

Vergleiche:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
my @array = ('a'..'f');
for( my $i = 0; $i <= $#array; $i++ ){
    print "Iteration über Index: $i\n";
}

# vs.

for( @array ){
    print "Iteration über Element: $_\n";
}
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
KurtZ
 2008-02-27 16:27
#106429 #106429
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
Quote
Nur speziell der Anweisungsblock fehlt doch hier, oder etwa nicht?? Ich komme mit der Schreibweise nicht so ganz klar!


Zum besseren Verständnis: for wird hier als Kurzschreibweise für foreach genutzt -> foreach
TMTOWTDYOG (there's more than one way to dig your own grave)
renee
 2008-02-27 17:50
#106433 #106433
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Gast+2008-02-27 13:01:44--
Ich kenne sie nur so, dass man in runden Klammern den Initialisierungsteil, Bedingungsteil und Re-Initialisierungsteil schreibt und anschließend in geschweiften Klammern den Anweisungsblock.
Nur speziell der Anweisungsblock fehlt doch hier, oder etwa nicht?? Ich komme mit der Schreibweise nicht so ganz klar!


Der Anweisungsblock ist vorne dran gestellt...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
murphy
 2008-02-27 18:23
#106434 #106434
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Gast+2008-02-27 13:01:44--
[...] Nur speziell der Anweisungsblock fehlt doch hier, oder etwa nicht?? Ich komme mit der Schreibweise nicht so ganz klar! [...]


mach_was for (@zeug); ist eine Kurzschreibweise für for (@zeug) { mach_was }, die nur dann funktioniert, wenn mach_was genau ein einziger Befehl ist.

Ferner ist for (@zeug) { ... } ein besonderes Kostrukt, das in etwa den gleichen Effekt wie my @temp = @zeug; while (@temp > 0) { local $_ = shift @temp; ... } hat, also einfach über alle Elemente der angegebenen Liste iteriert.

[Edit: Der Vergleich mit der while-Schleife mit temporärer Variable ist insofern korrekt, als bei einer foreach-Schleife die zu iterierende Liste stets vollständig im Speicher abgelegt wird, aber auch inkorrekt, da eine bereits in einer Variablen vorliegende Liste nicht kopiert wird und $_ sogar zu einem Alias der durchlaufenen Listenelemente wird, jede Modifkation daran also auch auf das Listenelement wirkt.]
When C++ is your hammer, every problem looks like your thumb.
KurtZ
 2008-02-27 18:35
#106435 #106435
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
renee+2008-02-27 16:50:24--
Der Anweisungsblock ist vorne dran gestellt...


Ach so... du hast in Perl oft die Wahlfreiheit bei einzeiligen Blocks diesen vorher oder dahinter zu schreiben (beim Stil scheiden sich die Geister)

also statt
Code (perl): (dl )
foreach (LISTE) {einzeiler}

geht auch
Code (perl): (dl )
einzeiler  foreach (LISTE)


beachte dass jetzt die Blockklammern fehlen. 'for' und 'foreach' sind äquivalent.

Wo das diese Postschreibweise explizit dokumentiert ist weiß ich leider nicht perlsyn

foreach erlaubt z.B. dann auch keine benannte Variable.

@Community: erlaubt mir perldoc auch eine Suche durch alle Docs um z.B. "foreach" zu suchen?

EDIT: habs in perlsyn gefunden:
Any simple statement may optionally be followed by a SINGLE modifier, just before the terminating semicolon (or block ending). The possible modifiers are:

if EXPR
unless EXPR
while EXPR
until EXPR
foreach EXPR
TMTOWTDYOG (there's more than one way to dig your own grave)
KurtZ
 2008-02-27 22:20
#106441 #106441
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
murphy+2008-02-27 17:23:27--
... bei einer foreach-Schleife die zu iterierende Liste stets vollständig im Speicher abgelegt wird,...


stets? nicht beim range Operator... :-) perlop#Range_Operators

Code (perl): (dl )
 for (1 .. 999_999_999) {print "$_\n"} 
TMTOWTDYOG (there's more than one way to dig your own grave)
murphy
 2008-02-28 01:13
#106443 #106443
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
@KurtZ: Wie auch die zitierte Dokumentation erwähnt, ist das leider erst eine Optimierung bei neueren Perlversionen. Außerdem gibt es andere Verwendungsmöglichkeiten, wo ein Zwischenspeichern genauso sinnlos ist, aber trotzdem durchgeführt wird (z.B. ... for (<>);).

Außerdem fehlt leider die Möglichkeit, Objekten eigener Klassen eine Iterationsfunktionalität zu verpassen :-(
When C++ is your hammer, every problem looks like your thumb.
betterworld
 2008-02-28 01:34
#106444 #106444
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
KurtZ+2008-02-27 17:35:43--
@Community: erlaubt mir perldoc auch eine Suche durch alle Docs um z.B. "foreach" zu suchen?


Die Standarddokumente wie "perlsyn" werden normalerweise alle in ein Verzeichnis installiert. Mit "locate perlsyn.pod" kannst Du es finden, bei mir ist es /usr/lib/perl5/5.8.8/pod/.

Den Rest macht grep -r.
KurtZ
 2008-02-28 02:50
#106445 #106445
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
@Betterworld:

POD Greppen? Dann kann ich eigentlich auch gleich googlen.
Ich hoffte auf etwas analoges zu perldoc -f um die Spezifikation zu finden

Den Pfad finde ich übrigens ohne locate komfortabel mit perldoc -l

Code: (dl )
1
2
$ perldoc -l perltoc
/usr/share/perl/5.8/pod/perltoc.pod


Alternativer Vorschlag: eine Suche durch perltoc!
Code: (dl )
man -P 'less -p foreach' perltoc

oder meinetwegen
Code: (dl )
grep foreach `perldoc -l perltoc`


Allerdings braucht die "perltoc" bei mir ewig bis sie angezeigt wird...

@Murphy:
perl5005delta - what's new for perl5.005
"foreach (1..1000000)" optimized

ist mir eigentlich neu genug

Quote
Außerdem fehlt leider die Möglichkeit, Objekten eigener Klassen eine Iterationsfunktionalität zu verpassen :-(


ähm ich verstehe dich nicht ganz, was hindert dich daran eine Klassenvariable anzulegen die ein Array aller Objektrefs ist.
(ungetesteter Code)

Code (perl): (dl )
foreach my $obj_ref (@Class::instances) {BLOCK}


oder eine Klassenmethode next() anzulegen:

Code (perl): (dl )
while ( Class->next( $obj_ref ) ) {BLOCK}


oder was möchtest du genau???

TMTOWTDYOG (there's more than one way to dig your own grave)
<< |< 1 2 >| >> 15 Einträge, 2 Seiten



View all threads created 2008-02-27 14:01.