Siechfred: $_[0] problem

Beitrag lesen

Ich versuche mal, das alles ein bisschen zusammenzufassen.

kurz und knapp: Ich mache eine eingabe sie kommt in eine subroutine wird umgewandelt und wieder ausgegeben.

Nein, sie wird eben nicht umgewandelt. Ich kommentiere mal Deinen Code häppchenweise:

#!/usr/bin/perl  
$a = <STDIN>;  #Eingabe ist "Hallo"  
chomp $a;  
print $a;

Hier legst Du eine Packagevariable an. Sie ist global und überall im Script ansprechbar. Übrigens, $a ist eine vordefinierte Perl-Variable, von der Du die Finger lassen solltest.

sub umwandeln  
{  
  my $wandel = shift;  
  $wandel = "Bye";  
}

Hier legst Du eine lexikalische Variable an. Sie gilt ausschließlich im umgebenden Block, hier in der Sub "umwandeln". Ist der Block beendet, ist $wandel nicht mehr gültig, sämtliche Manipulationen sind vergessen.

print $a;

Das gibt logischerweise "Hallo" aus.

Warum klappt das nicht? Wenn ich die sub aber so mache:
[...]
Geht es.

Das wurde denke ich ausreichend erläutert.

my $wandel = shift;
ist doch das ganz selbe wie
$_[0] oder versteh ich da etwas falsch?

In der Tat. Du kopierst die in der globalen Variablen $_[0] enthaltene Referenz in eine private Variable. Damit wirken alle Manipulationen an dieser privaten Variable nur im umgebenden Block, aber nicht außerhalb. Und deshalb bleibt der Inhalt von $a "Hallo". Man sollte es vermeiden, die zwei Variablensätze von Perl miteinander zu vermischen, es sei denn, man weiß wirklich, was man tut. Vielleicht hilft Dir zum Verständnis der Artikel Coping with Scoping weiter.

Du kommst auf mehreren Wegen aus dem Dilemma heraus. Entweder Du verwendest konsequent Packagevariablen (m.E. nicht mehr zeitgemäß):

$x = 'Hallo';  
umwandeln();  
print $x;  
  
sub umwandeln {  
  $x = 'Bye';  
}

Oder Du verwendest konsequent lexikalische Variablen:

my $x = 'Hallo';  
umwandeln();  
print $x;  
  
sub umwandeln {  
  $x = 'Bye';  
}

Oder so (m.E. der richtige Weg):

my $x = 'Hallo';  
$x = umwandeln($x);  
print $x;  
  
sub umwandeln {  
  my $arg = shift;  
  $arg = 'Bye';  
  return $arg;  
}

Der Code ist zwar ziemlicher Unsinn, hilft Dir aber möglicherweise, das Problem zu erkennen.

Siechfred