Hi
Wie ist dies zu erklären?
Was genau intern abläuft kann ich dir nicht sagen, aber innerhalb einer Routine dynamisch eine andere zu definieren ist komplexe "Metaprogrammierung".
Grob gesprochen: Beim zwoten durchlauf von test() wird $x mit my neu deklariert, ist also nicht mehr mit dem $x des ersten Durchlaufs identisch.(Speicherstelle).
Das sub untertest() wird aber von perl NICHT redefiniert und bleibt an dem $x des ersten Durchlaufs von test() gebunden.
Deswegen die Warnung:
Variable "$x" will not stay shared at /tmp/tst.pl line 10 (#1)
Will man aber unbedingt dynamisch neue subs erzeugen, die an privaten Variablen eines äußeren Scopes gebunden sind (sogenannte Closures), sollte man das _anonym_ tun, statt einen konkreten Namen (hier unterstest() zu geben.
use warnings;
use strict;
sub test
{
my $x = shift;
print "\n";
return sub {
print $x++," ";
}
}
my $sub_ref=test(0); #Sub-Referenz auf neue Unterroutine erhalten
$sub_ref->();
$sub_ref->();
$sub_ref->();
# 0 1 2
$sub_ref=test(10); #Sub-Referenz auf neue Unterroutine erhalten
$sub_ref->();
&$sub_ref(); # andere Schreibweise
&$sub_ref; # andere Schreibweise
# 10 11 12
*unterstest=test(20); # sub_ref auf Namen legen
unterstest();
unterstest();
unterstest();
# 20 21 22
{
no warnings; # Warnungen wg redefinition abschalten
*unterstest=test(30); # erneut sub_ref auf Namen legen
}
unterstest();
unterstest();
unterstest();
# 30 31 32
*unterstest=test(40); # erneut sub_ref auf Namen legen
# Warnung:
# Subroutine unterstest redefined at /tmp/tst.pl line 45
unterstest();
unterstest();
unterstest();
# 40 41 42
Alles klar?
Bye
Kurt