On Sat, 19 Aug 2006, Wes Gamble wrote:

> All,
>
> Why does this fail?
>
> irb(main):009:0> sprintf("%d", '08')
> ArgumentError: invalid value for Integer: "08"
>        from (irb):9:in `sprintf'
>        from (irb):9
>
> I assume it's because the 08 is being as an octal number prior to being
> changed to a decimal.  01 - 07 work fine, 09 breaks.
>
> But I'm telling sprintf to interpret it as decimal, so why can't I have
> leading zeroes?
>
> Please explain to me how this is expected behavior.
>
> Thanks,
> Wes

because:

     harp:~ > cat a.c
     main(){ char s[42]; int r = sprintf (s, "%d", 07); printf ("%d: <%s>\n", r, s); }


     harp:~ > gcc a.c
     harp:~ > a.out
     1: <7>


     harp:~ > cat a.c
     main(){ char s[42]; int r = sprintf (s, "%d", 08); printf ("%d: <%s>\n", r, s); }


     harp:~ > gcc a.c
     a.c: In function `main':
     a.c:1: numeric constant contains digits beyond the radix


ruby uses 'Integer(s)' to convert strings to ints and


     harp:~ > ri Kernel.Integer
     --------------------------------------------------------- Kernel#Integer
          Integer(arg)    => integer
     ------------------------------------------------------------------------
          Converts _arg_ to a +Fixnum+ or +Bignum+. Numeric types are
          converted directly (with floating point numbers being truncated).
          If _arg_ is a +String+, leading radix indicators (+0+, +0b+, and
          +0x+) are honored. Others are converted using +to_int+ and +to_i+.
          This behavior is different from that of +String#to_i+.

             Integer(123.999)    #=> 123
             Integer("0x1a")     #=> 26
             Integer(Time.new)   #=> 1049896590


     harp:~ > ruby -e'  Integer "07"  '

     harp:~ > ruby -e'  Integer "08"  '
     -e:1:in `Integer': invalid value for Integer: "08" (ArgumentError)
             from -e:1

so it's expected, documented, and consistent with c.

a good pattern to use is:


   harp:~ > ruby -e'  atoi = lambda{|s| Integer(s) rescue %r/(\d+)/.match(s)[1].to_i rescue raise ArgumentError, s};  p(atoi["08"]);  p(atoi["fubar"])  '
   8
   -e:1: fubar (ArgumentError)
           from -e:1


because simply falling back on to_i yields


   harp:~ > ruby -e'  atoi = lambda{|s| Integer(s) rescue s.to_i};  p(atoi["08"]);  p(atoi["fubar"])  '
   8
   0


regards.

-a
-- 
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama