[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Bug in sprintf?

Wes Gamble

8/18/2006 4:40:00 PM

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

--
Posted via http://www.ruby-....

23 Answers

William Crawford

8/18/2006 5:01:00 PM

0

Wes Gamble wrote:
> 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.

Because 8 isn't an octal number. 0-7 are octal.

--
Posted via http://www.ruby-....

Ara.T.Howard

8/18/2006 5:06:00 PM

0

William Crawford

8/18/2006 5:06:00 PM

0

William Crawford wrote:
> Wes Gamble wrote:
>> 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.
>
> Because 8 isn't an octal number. 0-7 are octal.

-slaps self- Think before you reply, William.

On second thought, this -does- seem wrong. It doesn't matter if you
tell it to be decimal, octal or hex, it all comes up with an error on 08
and 09, and not 00 to 07.

--
Posted via http://www.ruby-....

William Crawford

8/18/2006 5:06:00 PM

0

William Crawford wrote:
> William Crawford wrote:
>> Wes Gamble wrote:
>>> 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.
>>
>> Because 8 isn't an octal number. 0-7 are octal.
>
> -slaps self- Think before you reply, William.
>
> On second thought, this -does- seem wrong. It doesn't matter if you
> tell it to be decimal, octal or hex, it all comes up with an error on 08
> and 09, and not 00 to 07.

Last time, I swear.
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t... Says
that it IS trying to be octal because the 0 in front means that. (Why
it means that, I don't know.)

--
Posted via http://www.ruby-....

Carlos

8/18/2006 5:22:00 PM

0

ara.t.howard@noaa.gov wrote:

> 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
[...]
>> 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.
[...]
> because:
[...]
> ruby uses 'Integer(s)' to convert strings to ints and
[...]
> Kernel#Integer
[...]
> If _arg_ is a +String+, leading radix indicators (+0+, +0b+, and
> +0x+) are honored.
[...]
> so it's expected, documented, and consistent with c.

It is not expected, nor documented, because the documentation of sprintf
says:
d | Convert argument as a decimal number.

...which is very explicit in that the argument will be interpreted as a
decimal number, not octal.

Greetings.



Wes Gamble

8/18/2006 5:27:00 PM

0

Thanks for the comprehensive response.

Well, I can't really argue with the C implementation, of course...

BUT

it feels like if I declare my intent to interpret the sprintf input as a
_decimal_ number with %d (there's a %o if I wanted octal), that is
should allow for leading zeroes.

My intent in writing sprintf("%d", '08') is to say take the string 08
and turn it into the number 8.

It isn't to say here's an octal number, please convert it to decimal for
me. If I think the string is octal, I'll use %o for that.

So in the spirit of what the user expects, I still think this smells
bad.

Feel free to convince me otherwise.

Thanks again,
Wes

--
Posted via http://www.ruby-....

Wes Gamble

8/18/2006 5:28:00 PM

0

What Carlos said ;)

--
Posted via http://www.ruby-....

Jano Svitok

8/18/2006 5:40:00 PM

0

On 8/18/06, Wes Gamble <weyus@att.net> wrote:
> Thanks for the comprehensive response.
>
> Well, I can't really argue with the C implementation, of course...
>
> BUT
>
> it feels like if I declare my intent to interpret the sprintf input as a
> _decimal_ number with %d (there's a %o if I wanted octal), that is
> should allow for leading zeroes.
>
> My intent in writing sprintf("%d", '08') is to say take the string 08
> and turn it into the number 8.
>
> It isn't to say here's an octal number, please convert it to decimal for
> me. If I think the string is octal, I'll use %o for that.
>
> So in the spirit of what the user expects, I still think this smells
> bad.
>
> Feel free to convince me otherwise.
>
> Thanks again,
> Wes
>

As I see it, there are two separate things: WHAT number you want to
print, and HOW you want it print.

The latter one is specified by the format string.
The former one is specified by argument.

Think of sprintf("%d", 0x1234) or sprintf("%x", 123).

And it happens to be that '08' is in this case the same as 08 and that
is invalid octal number. QED. ;-)

Jano

Matthias Reitinger

8/18/2006 5:53:00 PM

0

Carlos wrote:

> It is not expected, nor documented, because the documentation of sprintf
> says:
> d | Convert argument as a decimal number.
>
> ...which is very explicit in that the argument will be interpreted as a
> decimal number, not octal.

I disagree on that. %d tells sprintf to expect an Integer as the
corresponding argument. Being given a String instead it tries to convert
it by calling Kernel#Integer. This fails for the reasons already
metioned.

Greetings, Matthias


--
Posted via http://www.ruby-....

Daniel Martin

8/18/2006 6:01:00 PM

0

Carlos <angus@quovadis.com.ar> writes:

> ara.t.howard@noaa.gov wrote:
>
>> On Sat, 19 Aug 2006, Wes Gamble wrote:
>>
>> so it's expected, documented, and consistent with c.
>
> It is not expected, nor documented, because the documentation of
> sprintf says:
> d | Convert argument as a decimal number.
>
> ...which is very explicit in that the argument will be interpreted as
> a decimal number, not octal.

I think that the problem here is that ruby is performing two
conversions, and the sprintf documentation only mentions one of them.

When you use '%d' in a sprintf(), ruby does a conversion of the
argument to an Integer using Kernel#Integer and then does the
conversion of the Integer to a portion of the output string as
documented.

Similarly, when you use %f in a sprintf(), ruby does a conversion of
the argument using Kernel#float and then does the conversion from
Float to part of the output string as documented.

So, we have:

sprintf("%d",'08') ==> ArgumentError
sprintf("%d",'8') ==> "8"
sprintf("%d",'08'.to_i) ==> "8"
sprintf("%f",'08') ==> "8.000000"

I think that if you're hitting this quirk in actual code, your code
needs so .to_i dropped in a few places. I'm actually surprised ruby
does those String=>Integer conversions at all.