$! is only set to a useful value if the function that you
call fails. If it succeeds, you cannot draw conclusions
from the value of $!. If you look at the source code of
File::Copy, you see that the move command first tries a
rename(). If that fails, it tries copying and unlinking.
But if the rename() fails, rename() sets $! Even if the
copy and unlink() succeeds.
The right way to test whether move() succeeds is by checking
its return value.
Abigail