in reply to octal number mysteriously changes after pass to subroutine
octal 0666 is equivalent to decimal 438.
octal 0777 is equivalent to decimal 511.
When you call fn(0666) , perl interprets 0666 as a number, and stores it as the integer value in the function @_ array. If you print $_[0]; then you will see the integer value in the default decimal representation; if you want to see the number as an octal, format it, like with printf "%#o", $_[0];
If you pass this value to a chmod using chmod(0666) or chmod($_[0]) then it will be properly interpreted as the right mode.
If you want to pass it as a string instead (your q(0666) example), then you can extract the underlying value (as shown in the chmod documentation) as chmod(oct(q(0666))) or chmod(oct($_[0])) .
In Section
Seekers of Perl Wisdom