"my" variables are lexically scoped. That is, they exist only within a certain portion of the text that is your source code. I have annotated your first example below to illustrate the various, overlapping, lexical scopes present.
1 use strict;
1
1 my $user_name;
1
1 $user_name = $ARGV[0];
1
1 print "IN SCRIPT: user_name == $user_name\n";
1
1 login();
1
1 print "IN SCRIPT: user_name == $user_name\n";
1
1 2 sub login {
1 2
1 2 print "IN SUBROUTINE: user_name == $user_name\n";
1 2 print "Can I change it in the subroutine?\n";
1 2 $user_name = "Bill";
1 2 print "IN SUBROUTINE: user_name == $user_name\n";
1 2
1 2}
1
Since $user_name was declared in the implicit/file-wide lexical scope (which I have labelled as "1"), it is available to all code within the source file (after the point at which it is declared). It comes as no surprise then that you can modify $user_name within a subroutine ... so long as the scope that $user_name was declared in overlaps the code that modifies it.