Tip du jour: no need to chomp before to_i

Discussion in 'Ruby' started by David A. Black, Oct 11, 2009.

  1. Hi --

    Very minor point, but in case it's useful:

    n = gets.chomp.to_i

    does the same thing as:

    n = gets.to_i

    because to_i doesn't do anything with the trailing newline anyway.

    This is even the case if you use the fussier Integer method. Integer
    is fussier in the sense that it doesn't like non-numeric strings:

    "123abc".to_i => 123
    Integer("123abc") => error

    But it doesn't mind whitespace:

    Integer("\t \n 123\n ") => 123

    so you can do Integer(gets) without chomping.

    I can't think of any exceptions or weird edge cases, but if you can,
    please report them :)


    David

    --
    The Ruby training with D. Black, G. Brown, J.McAnally
    Compleat Jan 22-23, 2010, Tampa, FL
    Rubyist http://www.thecompleatrubyist.com

    David A. Black/Ruby Power and Light, LLC (http://www.rubypal.com)
    David A. Black, Oct 11, 2009
    #1
    1. Advertising

  2. David A. Black wrote:
    > But it doesn't mind whitespace:
    >
    > Integer("\t \n 123\n ") => 123


    (leading and trailing whitespace that is)

    Beware that Integer() as well as being fussier, also implements special
    treatment of leading 0 (octal) and 0x (hex).

    >> "0123".to_i

    => 123
    >> Integer("0123")

    => 83
    >> "0x123".to_i

    => 0
    >> Integer("0x123")

    => 291
    --
    Posted via http://www.ruby-forum.com/.
    Brian Candler, Oct 13, 2009
    #2
    1. Advertising

  3. 2009/10/13 Brian Candler <>:
    > David A. Black wrote:
    >> But it doesn't mind whitespace:
    >>
    >> =A0 =A0Integer("\t =A0\n =A0123\n =A0") =A0 =A0=3D> 123

    >
    > (leading and trailing whitespace that is)
    >
    > Beware that Integer() as well as being fussier, also implements special
    > treatment of leading 0 (octal) and 0x (hex).
    >
    >>> "0123".to_i

    > =3D> 123
    >>> Integer("0123")

    > =3D> 83
    >>> "0x123".to_i

    > =3D> 0
    >>> Integer("0x123")

    > =3D> 291


    I have extended your test list a bit

    Ruby version 1.9.1
    irb(main):001:0> %w{123 0123 0x123 0b111}.each {|s| p s, s.to_i, Integer(s)=
    }
    "123"
    123
    123
    "0123"
    123
    83
    "0x123"
    0
    291
    "0b111"
    0
    7
    =3D> ["123", "0123", "0x123", "0b111"]

    Basically Integer applies the same semantics as the Ruby parser while
    #to_i just grabs the first sequence of digits, treats it as a decimal
    number and turns it into an int. If there is no such sequence it falls
    back to 0.

    Kind regards

    rober


    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Oct 13, 2009
    #3
  4. * Robert Klemme <> (2009-10-13) schrieb:

    > Basically Integer applies the same semantics as the Ruby parser while
    > #to_i just grabs the first sequence of digits, treats it as a decimal
    > number and turns it into an int. If there is no such sequence it falls
    > back to 0.


    A little correction: to_i is passed the radix, which by default is 10.

    It will return zero if the first character is not the set of digits for
    that radix, otherwise it will turn the run of digits at the front of the
    string into an integer according to the radix.

    mfg, simon .... l
    Simon Krahnke, Oct 19, 2009
    #4
  5. On 20.10.2009 00:49, Simon Krahnke wrote:
    > * Robert Klemme <> (2009-10-13) schrieb:
    >
    >> Basically Integer applies the same semantics as the Ruby parser while
    >> #to_i just grabs the first sequence of digits, treats it as a decimal
    >> number and turns it into an int. If there is no such sequence it falls
    >> back to 0.

    >
    > A little correction: to_i is passed the radix, which by default is 10.


    Thanks for correcting me!

    > It will return zero if the first character is not the set of digits for
    > that radix, otherwise it will turn the run of digits at the front of the
    > string into an integer according to the radix.


    You meant to say "the first _non whitespace_ character". :)

    Cheers

    robert


    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Oct 20, 2009
    #5
  6. * Robert Klemme <> (2009-10-20) schrieb:

    > On 20.10.2009 00:49, Simon Krahnke wrote:
    >> * Robert Klemme <> (2009-10-13) schrieb:
    >>
    >>> Basically Integer applies the same semantics as the Ruby parser while
    >>> #to_i just grabs the first sequence of digits, treats it as a decimal
    >>> number and turns it into an int. If there is no such sequence it falls
    >>> back to 0.

    >>
    >> A little correction: to_i is passed the radix, which by default is 10.

    >
    > Thanks for correcting me!
    >
    >> It will return zero if the first character is not the set of digits for
    >> that radix, otherwise it will turn the run of digits at the front of the
    >> string into an integer according to the radix.

    >
    > You meant to say "the first _non whitespace_ character". :)


    True. Whitespace at the start of the string seems to be ignored, but is
    a stopper everywhere else.

    It was complicated enough the way I wrote it. I looked for the ri
    documentation on to_i, but all the standard library ri docs seem to be
    gone on my computer, strange.

    I suppose the code is like this, only better:

    def to_i radix=10
    s = 0
    s += 1 while self[s,1] == "\s"
    (s...length).inject(0) | val, i |
    d = self[i,1] # wah!
    next val if d == '_'
    digit = radix_digit(d, radix)
    break val if digit < 0
    val *= radix
    val += digit
    end
    end

    mfg, simon .... l
    Simon Krahnke, Oct 22, 2009
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. cap
    Replies:
    4
    Views:
    112
  2. Doug Blackman
    Replies:
    7
    Views:
    105
    Robert Klemme
    Jan 28, 2011
  3. martin
    Replies:
    3
    Views:
    177
    Joe Smith
    Apr 15, 2006
  4. David Mark
    Replies:
    16
    Views:
    908
    Scott Sauyet
    Nov 11, 2011
  5. David Mark
    Replies:
    58
    Views:
    1,410
    David Mark
    Dec 6, 2011
Loading...

Share This Page