Bei deinem schlechten Englisch stehen einem ja die Haare zu Berge. Du darfst ruhig weiterhin auf deutsch schreiben.
Das Problem liegt daran, dass du wohl nicht siehst, dass der grep-Ausdruck in beiden Beispielen zuerst komplett ausgewertet wird (hottis Vermutung im Threadnachbar ist irreführend).
Zu if:
Das $_ im Block mit der Zuweisung ist dann ein komplett eigenständiges, also kein Alias für die Elemente aus den dereferenzierten Arrayreferenzen. Die Ausgabe von $_ nach der Anweisung zeigt dementsprechend auch nur
{
'Amount' => 158
}
Zu foreach:
foreach iteriert über die Liste und macht jeweils einen Alias für jedes Element. Der grep-Ausdruck liefert genau ein Listenelement. foreach dient als Topicaliser, daher ist das $_ der von dir erwartete Wert und der Funktionsweise des Codes deckt sich mit deinen Erwartungen. Noch einmal mit deutlicheren Worten: es geht, aber nur zufällig.
Alles in allem sind beide Versionen sehr bizarrer Code. Siehe hottis Codebeispiel, wie man's richtig macht. Ich würde es so schreiben:
my $testdata = …;
for (@$testdata) {
$_->{Amount} = 158 if 4654554 ~~ $_->{User};
}