Ask a Question related to Ruby, Design and Development.

  1. #1

    Default to_i

    Hi,

    taken from the ruby book:

    str.to_i -> anInteger

    Returns the result of interpreting leading characters in str as a decimal
    integer. Extraneous characters past the end of a valid number are ignored.
    If there is not a valid number at the start of str, 0 is returned. The
    method never raises an exception.

    example
    "hello".to_i
    »
    0

    Is there a way to recognize if the conversion was successful? If
    "0".to_i and "any string".to_i deliver the same result, I don't see how
    this could be accomplished, without separately checking the syntax of the
    given string.

    Why doesn't "hello".to_i deliver a nil as a return value, which can
    clearly be recognized as a conversion failure?

    Artur

    __________________________________________________ _____________________________
    Artur Merke
    ||| [email]artur.merke@udo.edu[/email]
    (O-O)
    _____________________________________________.oo0--(_)--0oo.___________________

    Artur Merke Guest

  2. Similar Questions and Discussions

    1. Destructive type conversion (to_i!, to_f!)
      Hi, There have been a few times in which I have wanted to destructively change the type of a variable, yet as fas I can determine there are only...
    2. Rational#to_i inconsistent with Float#to_i
      Float#to_i rounds toward zero; Rational#to_i rounds down (is equivalent to Rational#floor). This is inconsistent and complicates the replacing of...
  3. #2

    Default Re: to_i

    >>>>> "A" == Artur Merke <merke@ls1.cs.uni-dortmund.de> writes:

    A> Is there a way to recognize if the conversion was successful? If
    A> "0".to_i and "any string".to_i deliver the same result, I don't see how
    A> this could be accomplished, without separately checking the syntax of the
    A> given string.

    You have the method Integer to do this

    svg% ruby -e 'p Integer("0")'
    0
    svg%

    svg% ruby -e 'p Integer("hello")'
    -e:1:in `Integer': invalid value for Integer: "hello" (ArgumentError)
    from -e:1
    svg%

    svg% ruby -e 'a = Integer("hello") rescue 12; p a'
    12
    svg%


    --

    Guy Decoux
    ts Guest

  4. #3

    Default Re: to_i


    "Artur Merke" <merke@ls1.cs.uni-dortmund.de> schrieb im Newsbeitrag
    news:Pine.LNX.4.33.0311101726040.17966-100000@as0203.cs.uni-dortmund.de...
    Hi,

    taken from the ruby book:

    str.to_i -> anInteger

    Returns the result of interpreting leading characters in str as a decimal
    integer. Extraneous characters past the end of a valid number are ignored.
    If there is not a valid number at the start of str, 0 is returned. The
    method never raises an exception.

    example
    "hello".to_i
    »
    0

    Is there a way to recognize if the conversion was successful? If
    "0".to_i and "any string".to_i deliver the same result, I don't see how
    this could be accomplished, without separately checking the syntax of the
    given string.

    Why doesn't "hello".to_i deliver a nil as a return value, which can
    clearly be recognized as a conversion failure?

    IMHO this is a struggle between convenience and cleanness. I guess
    Matz decided for convenience in this case, maybe because in most cases
    using 0 is ok. If you want to do correct input checking you do
    /^[+-]?\d+$/ =~ foo anyway.

    Kind regards

    robert

    Robert Klemme Guest

  5. #4

    Default Re: to_i

    On Mon, 10 Nov 2003 17:44:36 +0100, Robert Klemme wrote:
    >
    > "Artur Merke" <merke@ls1.cs.uni-dortmund.de> schrieb im Newsbeitrag
    > news:Pine.LNX.4.33.0311101726040.17966-100000@as0203.cs.uni-dortmund.de...
    [snip]
    > Why doesn't "hello".to_i deliver a nil as a return value, which can
    > clearly be recognized as a conversion failure?
    >
    > IMHO this is a struggle between convenience and cleanness. I guess
    > Matz decided for convenience in this case, maybe because in most cases
    > using 0 is ok. If you want to do correct input checking you do
    > /^[+-]?\d+$/ =~ foo anyway.

    Something like this:


    server> expand -t2 c.rb
    def atoi(str)
    return str.to_i if /^\d+$/ =~ str
    raise "Cannot convert"
    end

    p atoi("42") #-> 42
    #p atoi("i18n") #-> exception
    #p atoi("0.42") #-> exception
    server>
    Simon Strandgaard Guest

  6. #5

    Default Re: to_i

    > IMHO this is a struggle between convenience and cleanness. I guess
    > Matz decided for convenience in this case, maybe because in most cases
    > using 0 is ok. If you want to do correct input checking you do
    > /^[+-]?\d+$/ =~ foo anyway.
    >
    IMO, it has to do with the principle of least surprise, and it is a BIG
    surprise to get
    "hello".to_i -> 0
    I think this should be viewed more general (not just for the methods to_i,
    to_f etc.). If the application of a method makes no sense for an input,
    then a nil value makes more sense as a return value (and shouldn't
    surprise anybody), then an arbitrary ambiguous value.

    Artur

    Artur Merke Guest

  7. #6

    Default Re: to_i


    "Artur Merke" <merke@ls1.cs.uni-dortmund.de> schrieb im Newsbeitrag
    news:Pine.LNX.4.33.0311111240420.23480-100000@as0203.cs.uni-dortmund.de...
    > > IMHO this is a struggle between convenience and cleanness. I
    guess
    > > Matz decided for convenience in this case, maybe because in most cases
    > > using 0 is ok. If you want to do correct input checking you do
    > > /^[+-]?\d+$/ =~ foo anyway.
    > >
    > IMO, it has to do with the principle of least surprise, and it is a BIG
    > surprise to get
    > "hello".to_i -> 0
    > I think this should be viewed more general (not just for the methods
    to_i,
    > to_f etc.).
    This is clearly dependent on the nature of the expectations, as your
    posting demonstrates. If you expect to_i to return a number you'd be very
    surprised to find nil there and see something like this:

    14:04:17 [extranet]: ruby -e '1 + nil'
    -e:1:in `+': nil can't be coerced into Fixnum (TypeError)
    from -e:1
    14:13:25 [extranet]:
    > If the application of a method makes no sense for an input,
    > then a nil value makes more sense as a return value (and shouldn't
    > surprise anybody), then an arbitrary ambiguous value.
    It might very well be that in most cases using 0 as value is ok. I'm not
    in a position to estimate the amounts of either sort of situation. I just
    guess that Matz decided to do it this way. IMHO both solutions can be
    justified. Moreover, there's a third solution equally reasonable: make
    to_i throw an exception if the instance at hand cannot be converted into a
    number.

    But in a way returning nil or throwing an exception would break the
    pattern of the to_XYZ methods: they always return something. Even to_a
    creates an array if the instance at hand is not a collection type at all.
    If to_a would return nil or throw in those cases you'd always have to do
    error checking, which you don't have to with the current implementation:

    def print_all(obj)
    obj.to_a.each {|e| puts e}
    end

    This works with all instances equally well because to_a behaves the way it
    does.

    Often there are more reasonable solutions and one has to pick one. In
    this case it defeats your expectations but maybe it doesn't for many
    others...

    Kind regards

    robert

    Robert Klemme Guest

  8. #7

    Default Re: to_i

    On Mon, 17 Nov 2003 10:24:58 +0900, Artur Merke wrote:
    >> IMHO this is a struggle between convenience and cleanness. I guess
    >> Matz decided for convenience in this case, maybe because in most cases
    >> using 0 is ok. If you want to do correct input checking you do /^[+-
    >> ]?\d+$/ =~ foo anyway.
    >>
    > IMO, it has to do with the principle of least surprise, and it is a BIG
    > surprise to get "hello".to_i -> 0
    [url]http://www.cplusplus.com/ref/cstdlib/atoi.html[/url]

    It is common for integer conversion techniques to use only what is known
    (e.g., "123hello" => 123; "hello" => 0). Delphi's StrToInt method, however,
    will throw an error (in some silly cases, IMO).

    -austin
    --
    austin ziegler * [email]austin@halostatue.ca[/email] * Toronto, ON, Canada
    software designer * pragmatic programmer * 2003.11.16
    * 23.21.40



    Austin Ziegler Guest

  9. #8

    Default Re: to_i

    Hi!

    * Artur Merke; 2003-11-17, 14:20 UTC:
    > IMO, it has to do with the principle of least surprise, and it is a
    > BIG surprise to get
    > "hello".to_i -> 0
    Let me quote Kernighan & Richie, Programming in C (naive
    implementation of atoi):

    int atoi(char s[])
    {
    int i, n;

    n = 0;
    for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
    n = 10 * n + (s[i] - '0');
    return n;
    }

    Assuming this sample implementation it is not at all surprising that
    atoi returns 0 if the argument string does not start with a 'digit'.
    Given Ruby's C heritage it is no surprise that to_i behaves the same
    as atoi.

    Josef 'Jupp' Schugt
    --
    .-------.
    message > 100 kB? / | |
    sender = spammer? / | R.I.P.|
    text = spam? / ___| |___

    Josef 'Jupp' SCHUGT Guest

  10. #9

    Default Re: to_i

    Hi,

    you don't really want to compare ruby with c! BTW, what you have overlooked
    is the fact, that c doesn't have a nil return value (0 is only a nil value
    in connection with pointers, not integers), so Kernighan & Richie havn't
    had another option then to return 0, but in ruby you have a nil value, and
    I'm pretty sure ;-), K&R would have chosen to return nil in ruby's to_i
    method.

    Artur


    On Tue, 18 Nov 2003, Josef 'Jupp' SCHUGT wrote:
    > Hi!
    >
    > * Artur ; 2003-11-17, 14:20 UTC:
    > > IMO, it has to do with the principle of least surprise, and it is a
    > > BIG surprise to get
    > > "hello".to_i -> 0
    >
    > Let me quote Kernighan & Richie, Programming in C (naive
    > implementation of atoi):
    >
    > int atoi(char s[])
    > {
    > int i, n;
    >
    > n = 0;
    > for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
    > n = 10 * n + (s[i] - '0');
    > return n;
    > }
    >
    > Assuming this sample implementation it is not at all surprising that
    > atoi returns 0 if the argument string does not start with a 'digit'.
    > Given Ruby's C heritage it is no surprise that to_i behaves the same
    > as atoi.
    >
    > Josef 'Jupp' Schugt
    > --
    > .-------.
    > message > 100 kB? / | |
    > sender = spammer? / | R.I.P.|
    > text = spam? / ___| |___
    >
    >
    Artur Merke Guest

  11. #10

    Default Re: to_i


    "Artur Merke" <merke@ls1.cs.uni-dortmund.de> schrieb im Newsbeitrag
    news:Pine.LNX.4.33.0311191036400.23486-100000@as0203.cs.uni-dortmund.de...
    > Hi,
    >
    > you don't really want to compare ruby with c! BTW, what you have
    overlooked
    > is the fact, that c doesn't have a nil return value (0 is only a nil value
    > in connection with pointers, not integers), so Kernighan & Richie havn't
    > had another option then to return 0, but in ruby you have a nil value, and
    > I'm pretty sure ;-), K&R would have chosen to return nil in ruby's to_i
    > method.
    IMHO there are three reasonable ways to deal with the situation that an item
    does not correspond to an integer value:

    1) return a specific int value - notably 0.

    2) retun a specific non int value - notably nil.

    3) throw an exception.

    I'd say from a theoretical point of view option 3) is the cleanest. The
    exception signals that there is no int representation for the specific item
    at hand. In this case I'd prefer not to have to_i in such classes and then
    we get no such method error. And, we can check beforehand whether the
    conversion will succeed. Drawback: code must catch the exception or do the
    check or will be terminated for some values.

    Option 1) is next best IMHO, because it ensures that all code will continue
    to work although in some cases we will see irritating results because 0 is
    the neutral element for addition but not for multiplication etc.

    Option 2) is worst since it neither ensures that code works (nil is not an
    integer, so math will fail) nor can we omit the check of the converted value
    like we can do with exceptions:

    n = item.to_i
    return false if n.nil?
    len = n + 5
    # ...

    # vs.

    begin
    len = item.to_i + 5
    # ...
    rescue NoMethodError
    return false
    end

    Note, that math might not be a too good an example because then tyically one
    uses 5 + item and lets coercion to the job (i.e. throw an exception if item
    can't be coerced).

    I guess that Matz decided to go for opt 1) because it is the best from a
    pragmatic point of view.

    Regards

    robert

    > Artur
    >
    >
    > On Tue, 18 Nov 2003, Josef 'Jupp' SCHUGT wrote:
    > > Hi!
    > >
    > > * Artur ; 2003-11-17, 14:20 UTC:
    > > > IMO, it has to do with the principle of least surprise, and it is a
    > > > BIG surprise to get
    > > > "hello".to_i -> 0
    > >
    > > Let me quote Kernighan & Richie, Programming in C (naive
    > > implementation of atoi):
    > >
    > > int atoi(char s[])
    > > {
    > > int i, n;
    > >
    > > n = 0;
    > > for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
    > > n = 10 * n + (s[i] - '0');
    > > return n;
    > > }
    > >
    > > Assuming this sample implementation it is not at all surprising that
    > > atoi returns 0 if the argument string does not start with a 'digit'.
    > > Given Ruby's C heritage it is no surprise that to_i behaves the same
    > > as atoi.
    > >
    > > Josef 'Jupp' Schugt
    > > --
    > > .-------.
    > > message > 100 kB? / | |
    > > sender = spammer? / | R.I.P.|
    > > text = spam? / ___| |___
    > >
    > >
    >
    Robert Klemme Guest

  12. #11

    Default Re: to_i

    Hi,

    In message "Re: to_i"
    on 03/11/20, "Robert Klemme" <bob.news@gmx.net> writes:

    |I guess that Matz decided to go for opt 1) because it is the best from a
    |pragmatic point of view.

    I provided both (to_i for opt1, Integer() for opt2).

    matz.


    Yukihiro Matsumoto Guest

  13. #12

    Default Re: to_i

    Hi!

    No TOFU (Text on-top of full quote) please, thank you.

    * Artur Merke; 2003-11-19, 13:45 UTC:
    > you don't really want to compare ruby with c! BTW, what you have
    > overlooked is the fact, that c doesn't have a nil return value (0
    > is only a nil value in connection with pointers, not integers), so
    > Kernighan & Richie havn't had another option then to return 0, but
    > in ruby you have a nil value, and I'm pretty sure ;-), K&R would
    > have chosen to return nil in ruby's to_i method.
    They wouldn't because nil is an instance of NilClass not an instance
    of String. It would be a big surprise if a method sometimes returns
    this class and sometimes returns that class (unless of course one
    class is a subclass of the other one or both classes have a common
    superclass).

    I therefore expect to_i to behave like to_s, the latter defaulting to
    "" if no senseful representation is being found. If to_s returns
    string version of nothing in such cases it would be a big surprise if
    to_i would not return the numerical version of nothing - which is 0.

    The obvious alternative to returning something unexpected is to raise
    an exception indicating that something unexpected was encountered. It
    would make perfect sense if to_i would raise an ArgumentError. For
    this reason there are *two* ways of convering strings to numbers.

    - Sending the to_i message is the non-exception-throwing variant.

    - Applying the Integer operator is the exception-throwing variant.

    Just my 0.02 EUR,

    Josef 'Jupp' Schugt
    --
    .-------.
    message > 100 kB? / | |
    sender = spammer? / | R.I.P.|
    text = spam? / ___| |___


    Josef 'Jupp' SCHUGT Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139