Brooks Davis wrote:

> The behavior of sprintf("%d", str) is not what I would expect.  If str
> begins with a '0', for example "01", it is treated as an octal number.
> This seem odd because I would expect the following two lines to be the
> same:
> 
> sprintf("%d", str)
> sprintf("%d", str.to_i)
> 
> This is not the case:
> 
> irb(main):006:0> str="08"
> => "08"
> irb(main):007:0> sprintf("%d", str)
> ArgumentError: invalid value for Integer: "08"
>         from (irb):7:in `sprintf'
>         from (irb):7
> irb(main):008:0> sprintf("%d", str.to_i)
> => "8"
> irb(main):009:0> str="010"
> => "010"
> irb(main):010:0> sprintf("%d", str)
> => "8"
> irb(main):011:0> sprintf("%d", str.to_i)
> => "10"
> 
> The seems to violate POLA.  In my case it was quite astonishing because
> I had a script where I parse strings like "r01rpc2" to find the rack and
> power controller number from a string.  When I added my eighth rack, the
> script stopped working after several years of operation.  Is this
> behavior intended?  The documentation on rubycentral doesn't really say
> one way or another.
> 


This behavior is a little odd. The documentation for String#to_i (A bit 
out of date here: 
http://www.rubycentral.com/book/ref_c_string.html#String.to_i) says that 
if no arg is passed to to_i(), then the default base is 10. The string 
is then evaluated in that base, so leading 0's are ignored. If a base of 
0 is given, then to_i() looks for leading '0', '0b', '0o', '0d', or '0x' 
to determine the base. The method never raises an exception, but returns 
0 instead when no valid number is found.
Thus:
irb(main):255:0> "08".to_i
=> 8
irb(main):256:0> "08".to_i(0)   #Viewed as octal. '8' is invalid digit.
=> 0
irb(main):257:0> "07".to_i(0)    #Octal
=> 7
irb(main):258:0> "7".to_i(0)    #Decimal
=> 7


sprintf() appears to interpret numeric strings differently--in line with 
the rules for numeric literals in Ruby:
irb(main):261:0> 08
SyntaxError: compile error
(irb):261: Illegal octal digit
         from (irb):261
irb(main):262:0> sprintf("%d", "08")
ArgumentError: invalid value for Integer: "08"
         from (irb):262:in `sprintf'
         from (irb):262
irb(main):263:0> sprintf("%d", "0d8")
=> "8"

I would suggest you stick with explicitly calling to_i.

David Sletten