http://qs321.pair.com?node_id=11150074


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])) .

Replies are listed 'Best First'.
Re^2: octal number mysteriously changes after pass to subroutine
by Anonymous Monk on Feb 01, 2023 at 19:46 UTC
    Thank you pryrt++

    Here's another conundrum, why don't these behave the same:

    perl -le '$n=0666; print $n'
    438
    perl -le '$n=shift; print $n' 0666
    0666

      The one embedded in the source code is an octal number string literal to Perl. The other is a string to Perl, as it comes from @ARGV.

      If you want to treat incoming parameters as octal, see the oct function.

      Updated: s/number string/number literal/, suggested by LanX

      There are fundamental things in Perl, which might be confusing here

      1. a scalar variable can be a number or a string (or a reference ...)
      2. There are various literal notations in code
      3. literals like "txt" , 'txt' , q(txt) , ... will produce the same string txt
      4. literals like 016 , 0xE , 14 will produce the same number (well integer) 14
      5. a string might look like a literal notation of a number like "016" , but literal notation inside strings will not be interpreted
      6. an implicit string to number conversion will always be decimal, hence "016" + 3  == 19 not 17
      7. if you want another base, you need to convert the string explicitly by yourself
      8. one (dangerous) way is eval("016") == 14

      I hope it's clearer now.

      Cheers Rolf
      (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
      Wikisyntax for the Monastery

      Arguments are received as strings. The second is equivalent to

      perl -le '$n="0666"; print $n'
      and
      perl -le '$n=q(0666); print $n'