0

Which should I use as I had just started learning Ruby for web development use, so shall we use this for such below example:

print "Type your chosen number?"
user_number = Integer(gets.chomp)

Or

print "Type your chosen number?"
user_number = gets.chomp.to_i 
Chris
  • 26,361
  • 5
  • 21
  • 42
Saoud ElTelawy
  • 197
  • 1
  • 3
  • 15

3 Answers3

4

It depends

If you need exception -- Integer(gets)

If no -- gets.to_i or Integer(gets, exception: false)

In any case you don't need chomp

Integer("1") # => 1
Integer("1.0") # raise ArgumentError
Integer("blabla") # raise ArgumentError
Integer("blabla", exception: false) # => nil

"1".to_i # => 1
"1.0".to_i # => 1
"blabla".to_i # => 0
mechnicov
  • 12,025
  • 4
  • 33
  • 56
  • Thanks a lot, why I don't need to use chomp [I think I have to use if for not make a line break or spaces] ? – Saoud ElTelawy Sep 09 '22 at 22:53
  • 1
    @SaoudElTelawy [`String#to_i`](https://ruby-doc.org/core/String.html#method-i-to_i) and [`Kernel#Integer`](https://ruby-doc.org/core/Kernel.html#method-i-Integer) work such way. They ignore extra whitespaces – mechnicov Sep 09 '22 at 23:39
  • 1
    `to_i` defaults to base 10 but for `Integer()` you have to pass `10` as the 2nd argument explicitly if you don't want it to auto-detect the base. – Stefan Sep 10 '22 at 08:46
1

I can't tell you which method would be better. The answer depends too much on a number of other factors. I will add this though:

In addition to some of the other things mentioned by others, Integer() will also convert all sorts of other seemingly non numeric values that are using radix indicators in order to utilize Binary, Hexidecimal, and Octal number systems. This in turn can result in potentially unexpected results or even errors for what might otherwise seem like a valid numeric entry. A few examples:

Integer("0x1a")  #=> 26
Integer("0x9f")  #=> 159
Integer("0b01")  #=> 1
Integer("0b010")  #=> 2
Integer("0b011")  #=> 3
Integer("0b02")  #=> Evaluation Error
Integer("010")  #=> 8
Integer("011")  #=> 9
Integer("0110")  #=> 72
Integer("01100")  #=>576
Integer("01101")  #=>577
Integer("01")  #=> 1
Integer("07")  #=> 7
Integer("08")  #=> Evaluation Error
0

In general you should ask an object to do something rather than do something to an object; the object knows best. object.do_thing asks the object to do a thing. do_thing(object) does the thing to the object, and assumes it knows best.

However, in this specific case, they are subtly different. The major difference is that String#to_i will return 0 if you try to convert nonsense. Whereas Kernel#Integer will throw an exception.

# Prints 0
p "not a number".to_i

# (file): invalid value for Integer(): "not a number" (ArgumentError)
p Integer("not a number")

In general you should prefer to raise an exception on failure, that is more important. Methods which do not throw exceptions on bad input make for difficult to find bugs, it's better to fail fast and as close to the actual problem as possible. If you want you can catch the exception.

Schwern
  • 153,029
  • 25
  • 195
  • 336