Schrift
[thread]6692[/thread]

'return' und 'or': Operatorenrangfolge

Leser: 1


<< |< 1 2 >| >> 13 Einträge, 2 Seiten
Crian
 2005-02-07 17:49
#51570 #51570
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
Ich hab eine ganze Weile an einem Problem gesessen, bis ich es auf dieses hier zurückführen konnte:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/perl
use strict;
use warnings;

sub vergleiche1 ($$) {
   my ($aa, $bb) = @_;
   print "1: aa = '$aa', ", length($aa), "\1: nbb = '$bb', ", length($bb), "\n";
   print "1: aa ist leer\n" if $aa eq '';
   print "1: bb ist leer\n" if $bb eq '';
   return $aa eq '' or
          $bb eq '' or
          $aa eq $bb;
};

sub vergleiche2 ($$) {
   my ($aa, $bb) = @_;
   print "2: aa = '$aa', ", length($aa), "\n2: bb = '$bb', ", length($bb), "\n";
   print "2: aa ist leer\n" if $aa eq '';
   print "2: bb ist leer\n" if $bb eq '';
   return $aa eq '' ||
          $bb eq '' ||
          $aa eq $bb;
};

sub vergleiche3 ($$) {
   my ($aa, $bb) = @_;
   print "3: aa = '$aa', ", length($aa), "\n3: bb = '$bb', ", length($bb), "\n";
   print "3: aa ist leer\n" if $aa eq '';
   print "3: bb ist leer\n" if $bb eq '';
   return ($aa eq ''  or
           $bb eq ''  or
           $aa eq $bb   );
};


{
   my $eins = 'blubb';
   my $zwei = '';

   print "TEST EINS\n";
   my $t1 = vergleiche1($eins, $zwei);
   print "Ergebnis: [$t1]\n\n";

   print "TEST ZWEI\n";
   my $t2 = vergleiche2($eins, $zwei);
   print "Ergebnis: [$t2]\n\n";

   print "TEST DREI\n";
   my $t3 = vergleiche3($eins, $zwei);
   print "Ergebnis: [$t3]\n\n";

}


Ausgabe:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
TEST EINS
1: aa = '', 0
1: bb = 'blubb', 5
1: aa ist leer
Ergebnis: []

TEST ZWEI
2: aa = '', 0
2: bb = 'blubb', 5
2: aa ist leer
Ergebnis: [1]

TEST DREI
3: aa = '', 0
3: bb = 'blubb', 5
3: aa ist leer
Ergebnis: [1]


Belegt man $eins und $zwei andersherum, so ist das Ergebnis in allen drei Fällen '1'.

Deshalb funktioniert es manchmal so wie es soll, manchmal auch nicht.

Das Problem ist wohl, dass return stärker bindet als or!

Und das finde ich ziemlich eigenartig. welchen Sinn kann es wohl haben, return stärker als irgendwas anderes binden zu lassen? Welcher Ausdruck hinter dem return würde denn Sinn machen, wenn er dort stehen bliebe?

Es wurde leider auch nicht gewarnt, dass der Code hinter return $aa eq '' nicht ausgeführt wurde.


Dies Beispiel soll zur Warnung dienen, damit so schnell kein anderer in diese Falle tritt.

Zum Glück hat man bei Perl ja nur ganz selten mal so einen Fall, wo man mit Intuition einfach genau daneben liegt.
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
Ishka
 2005-02-07 19:14
#51571 #51571
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
wobei ich es eher intuitiv finde, daß or schwächer bindet, als funktionsaufrufe. Und es besser finde, daß hier nicht zwischen verschiedenen Funktionen unterscheiden wird, als die paar Fälle, wo das or dahinter keinen Sinn macht (exit, die, next, return, ..) anders zu behandeln.
sub z{if(@_){1while$x[$k=rand 10];t($t=$x[$k]=1)}print map"$z[$x[$_]]$_".($_%3?
"":"\n"),1..9}sub t{$j=0;$x[$_+1]==$t&&($j+=2**$_)for 0..8;z,die"Gewinner $z[$t]
"if grep$_==($j&$_),7,56,73,84,146,273,292,448;z,die"Gleichstand\n"if@x>9&&!grep
!$_,@x}@x=4;@z=qw{. [ (};z$^T&1;while(<>){next if$_>9||$x[$_];t$t=$x[$_]=2;z 1}
Crian
 2005-02-07 19:37
#51572 #51572
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
return ist imho keine Funktion
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
kabel
 2005-02-07 19:49
#51573 #51573
User since
2003-08-04
704 Artikel
BenutzerIn
[default_avatar]
perldoc -f return ... ob man daraus folgern kann, dass return eine funktion ist?
-- stefan
betterworld
 2005-02-07 20:14
#51574 #51574
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
Durch Ausprobieren laesst sich herausfinden, dass return sich anscheinend gemäß der Operatorenreihenfolge, die in perlop beschrieben wird, wie ein "list operator" verhält -- sogar, wenn die Funktion in einem skalaren Kontext steht. Schade eigentlich.. denn wenn die Ausführungsreihenfolge vom Kontext abhängen würde, wäre das mal ein lustiges Feature ;)
murphy
 2005-02-07 20:16
#51575 #51575
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Meiner Meinung nach ist return eine "Unfunktion" schlechthin, genauso, wie auch der Aufruf einer Funktion an sich keine Funktion ist. Das Erzeugen und Verlassen eines Stackframes gehört auf allen mir bekannten modernen Computerarchitekturen zu den elementaren Operationen und kann gar nicht durch Funktionen einer Hochsprache ausgedrückt werden.

Im Gegensatz dazu sind Operationen wie exit oder die tatsächlich Funktionen, die sogar zurückkehren könnten, wenn sie denn wollten, da sie eben wie Funktionen unter Erzeugung eines Stackframes aufgerufen werden.

Return kann nur dann unter Umständen als funktionsähnliches Objekt gesehen werden, wenn man sich in einer Welt bewegt, die das Konzept eines Stacks nicht kennt und ganz andere Formen von Funktionsaufrufen benutzt. Das ist aber bei Perl nicht der Fall.

Abgesehen von solch theoretischen Überlegungen ist es schlicht unpraktisch, return nicht das niedrigste mögliche Binding zuzuweisen. Und es ist auch im Vergleich zu anderen Sprachen recht ungewöhnlich.
When C++ is your hammer, every problem looks like your thumb.
kabel
 2005-02-07 21:16
#51576 #51576
User since
2003-08-04
704 Artikel
BenutzerIn
[default_avatar]
laut perlop ist eine funktion aber nur dann ein list term, wenn die argumente in klammern stehen.

den ersten absatz verstehe ich nicht. in hochsprachen will ich vom stack nix mehr sehen.
hast du ein beispiel für eine architektur, die du im vorletzten absatz angesprochen hast?

return ist ein statement, dass der speicherstelle, an der der aufrufer den funktionswert erwartet, einen wert zuweist. think pascal ;-) oder meinetwegen C, wo es durch das fehlen der klammern sichtbar ist, dass return keine funktion ist. es ist nur zucker.\n\n

<!--EDIT|kabel|1107803869-->
-- stefan
esskar
 2005-02-07 21:30
#51577 #51577
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
klar, return ist eine funktion;
das hatten wir auch schonmal diskutiert, glaube ich!
benutz doch einfach variante 1 ohne return... dann hast du es oder benutz return richtig wie in 3 (also mit Klammern - Funktionsaufruf eben )
murphy
 2005-02-08 00:48
#51578 #51578
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
[quote=kabel,07.02.2005, 20:16]den ersten absatz verstehe ich nicht. in hochsprachen will ich vom stack nix mehr sehen.
hast du ein beispiel für eine architektur, die du im vorletzten absatz angesprochen hast?[/quote]
Auch Perl verwendet ja intern einen Stack für die Parameter und Rückgabewerte von Funktionen. Und auch wenn der Programmierer sich (hoffentlich) nicht den Kopf darüber zerbrechen muss, ist return ein Konstrukt, dass diesen Stack modifiziert.

Ich kenne keine Maschinenarchitektur ohne Stack, aber ein paar Sprachen benutzen ihn nicht oder nur indirekt für den Kontrollfluss bei Funktionsaufrufen (zum Beispiel CHICKEN).
When C++ is your hammer, every problem looks like your thumb.
kabel
 2005-02-08 08:29
#51579 #51579
User since
2003-08-04
704 Artikel
BenutzerIn
[default_avatar]
naja der absatz klingt so als ob du es schade findest dass man den stack nicht manipulieren könnte ... ;-)

in den frühen fortran-versionen war rekursion verboten.
ob deswegen return als funktionsähnliches objekt gehandhabt wird? nee :cool:

rekursion _bedingt_ die existenz eines stacks. ob er explizit da ist oder implizit in anderen objekten verborgen, spielt keine rolle.\n\n

<!--EDIT|kabel|1107844517-->
-- stefan
<< |< 1 2 >| >> 13 Einträge, 2 Seiten



View all threads created 2005-02-07 17:49.