Zweimal shift macht Probleme

Zweimal shift macht Probleme

am 15.03.2007 01:29:19 von Florian Hess

Guten Tag,

$ perl -e 'use strict; my $h = {}; sub newname { shift->{name} = shift;
}; newname($h,"test");'
Can't use string ("test") as a HASH ref while "strict refs" in use at -e
line 1.

Ich habe doch als erstes Argument für newname eine Referenz auf einen
anonymen Hash mitgeben, oder?

Also wenn ihr mich fragt, sieht das aus wie ein Perl-Bug. Der Optimizer
scheint hier etwas voreilig beide shifts mit demselben Wert zu ersetzen.

Oder liegt der Fehler doch in meinem Code?


Florian Hess.

Re: Zweimal shift macht Probleme

am 15.03.2007 07:49:14 von Christian Lackas

* Florian Hess [2007-03-15]:

Hallo Florian,

> $ perl -e 'use strict; my $h = {}; sub newname { shift->{name} = shift;
> }; newname($h,"test");'
> Can't use string ("test") as a HASH ref while "strict refs" in use at -e
> line 1.
> Ich habe doch als erstes Argument für newname eine Referenz auf einen
> anonymen Hash mitgeben, oder?

Ja, das ist richtig.

> Also wenn ihr mich fragt, sieht das aus wie ein Perl-Bug. Der Optimizer
> scheint hier etwas voreilig beide shifts mit demselben Wert zu ersetzen.

Nein, das ist kein Bug in Perl. Der Fehler beruht auf der Annahme, dass
das shift auf der linken Seite vor dem auf der rechten Seite ausgeführt
wird. Dem ist allerdings nicht so:

#perl -w
use strict;
sub left : lvalue { print "left\n"; return }
sub right { print "right\n"; return }
left() = right();

ergibt

right
left

> Oder liegt der Fehler doch in meinem Code?

Und dein Beispiel funktioniert auch mit

newname("test", $h);

Es ist aber eher fraglich, ob das Ausnutzen solcher Seiteneffekte
sinnvoll ist. In vielen anderen Sprachen sind Dinge wie

++i == i++

schlicht undefiniert.

Kannst du vielleicht $_[0] und $_[1] verwenden?

Gruß
Christian

--
Murphys Law 30:
Die Masse des Trödels wird immer die Anzahl der Schubladen übersteigen.
http://www.lackas.net/ Perl Delphi Linux MP3 Searchengines Domainchecker
http://www.spect-ct.com/ NanoSPECT/CT multi-modality molecular imaging

Re: Zweimal shift macht Probleme

am 15.03.2007 09:24:09 von Frank Seitz

Christian Lackas wrote:
> * Florian Hess [2007-03-15]:
>>
>>$ perl -e 'use strict; my $h = {}; sub newname { shift->{name} = shift;
>>}; newname($h,"test");'
>>Can't use string ("test") as a HASH ref while "strict refs" in use at -e
>>line 1.
>>Ich habe doch als erstes Argument für newname eine Referenz auf einen
>>anonymen Hash mitgeben, oder?
>
> Ja, das ist richtig.
>
>>Also wenn ihr mich fragt, sieht das aus wie ein Perl-Bug. Der Optimizer
>>scheint hier etwas voreilig beide shifts mit demselben Wert zu ersetzen.
>
> Nein, das ist kein Bug in Perl. Der Fehler beruht auf der Annahme, dass
> das shift auf der linken Seite vor dem auf der rechten Seite ausgeführt
> wird. Dem ist allerdings nicht so:
>
> #perl -w
> use strict;
> sub left : lvalue { print "left\n"; return }
> sub right { print "right\n"; return }
> left() = right();
>
> ergibt
>
> right
> left

Formal ausgedrückt: = ist ein rechtsassoziativer Operator,
d.h. die rechte Seite wird vor der linken Seite ausgewertet.
Die Assoziativität der Perl-Operatoren ist in perdoc perlop
dokumentiert.

>>Oder liegt der Fehler doch in meinem Code?

Folglich ja.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: Zweimal shift macht Probleme

am 15.03.2007 11:06:02 von Florian Hess

Christian Lackas schrieb:
> * Florian Hess [2007-03-15]:
>
> Hallo Florian,
>

> Nein, das ist kein Bug in Perl. Der Fehler beruht auf der Annahme, dass
> das shift auf der linken Seite vor dem auf der rechten Seite ausgeführt
> wird.
Aha! Da lag mein Denkfehler, vielen Dank. Muss ich dieses mal
tatsächlich $_[0] und $_[1] nehmen.

>
> #perl -w
> use strict;
> sub left : lvalue { print "left\n"; return }
> sub right { print "right\n"; return }
> left() = right();
>
> ergibt
>
> right
> left
>

Das wundert mich jetzt, nimmt er das so sang- und klanglos hin? Meckert
er nicht, dass du mit left() an ein undef zuweist?


Danke (& an Frank),
Florian Heß.

Re: Zweimal shift macht Probleme

am 15.03.2007 12:07:59 von Ch Lamprecht

Florian Hess schrieb:
> Christian Lackas schrieb:
>
>>* Florian Hess [2007-03-15]:
>>
>>Hallo Florian,
>>
>
>
>>Nein, das ist kein Bug in Perl. Der Fehler beruht auf der Annahme, dass
>>das shift auf der linken Seite vor dem auf der rechten Seite ausgeführt
>>wird.
>
> Aha! Da lag mein Denkfehler, vielen Dank. Muss ich dieses mal
> tatsächlich $_[0] und $_[1] nehmen.
>
>
>> #perl -w
>> use strict;
>> sub left : lvalue { print "left\n"; return }
>> sub right { print "right\n"; return }
>> left() = right();
>>
>>ergibt
>>
>> right
>> left
>>
>
>
> Das wundert mich jetzt, nimmt er das so sang- und klanglos hin? Meckert
> er nicht, dass du mit left() an ein undef zuweist?
>

Das ist doch hier

undef = undef;

was links und rechts auf den selben SCALAR verweist, also wahrscheinlich gar
nicht ausgeführt wird.

Christoph


--
use Tk;use Tk::GraphItems;$c=tkinit->Canvas->pack;push@i,Tk::GraphItems ->
TextBox(text=>$_,canvas=>$c,x=>$x+=70,y=>100)for(Just=>anoth er=>Perl=>Hacker);
Tk::GraphItems->Connector(source=>$i[$_],target=>$i[$_+1])fo r(0..2);
$c->repeat(30,sub{$_->move(0,4*cos($d+=3.16))for(@i)});MainL oop