On Thu, Mar 13, 2014 at 10:35 PM,  <sto.mar / web.de> wrote:
> Am 11.03.2014 11:06, schrieb Robert Klemme:
>> On Tue, Mar 11, 2014 at 9:48 AM,  <chendihao / xiaomi.com> wrote:
>>> So many similar functions have been implemented(refer
>>> http://stackoverflow.com/questions/1235863/test-if-a-string-is-basically-an-integer-in-quotes-using-ruby
>>> and
>>> http://stackoverflow.com/questions/5661466/test-if-string-is-a-number-in-ruby-on-rails).
>>>
>>> But for DRY principle, is it better for Ruby to implement it? Maybe
>>> "is_number?" or "to_i?".
>>
>> No. There is already one standard solution.  Best is to just use
>> Integer and handle the exception.
>>
>> size = Integer(gets)
>
> "Best" is a matter of taste...

I'd say it's a matter of values: your values determine what you
consider better or worse. But of course there is a certain factor of
subjectivity here. OTOH there are best practices in the industry. :-)

> I prefer using a regex instead of raising and handling an exception,

Fact remains that you are duplicating the parsing code.  If at some
point in time what Integer() accepts as valid input changes (not very
likely in _this_ case) you have diverging implementations. Redundancy
is usually bad. Maybe it's a bit more obvious with floating point
numbers as the regexp to parse that is significantly more complex. You
don't really want

> since I consider wrong user input not to be exceptional.

Well, nobody said you need to let the exception escape the user input
routine. Advantage of using exceptions is that you only have one
operation (the conversion to int) and proceed normally if it succeeds;
if it fails you take another code path.

Usually it's better to execute an operation and deal with failure than
to try to determine whether it will work, execute it - and still have
to deal with failure.  This is especially true for situations where
conditions can change between the check and the operation which allow
the operation still to fail. Typical example is: you check network
connectivity (e.g. to a database) and then do the actual connection.
You always have to deal with potential connection failures, even if
the check succeeded.  So you are making the code more complicated and
do not gain anything.

>> You can even catch in line if you really need to use this in a branch condition
>>
>> size = Integer(gets) rescue nil
>
> I strongly disagree, you should *never* do that.
>
> Consider e.g. a stupid typo in the code, like:
>
>   size = Integer(getss)  rescue nil
>
> This would **not** raise any exception, but you certainly would
> want it to raise one (NameError).

That will be apparent quite soon during testing. You'll also get
another exception when using the object as an integer.

$ ruby -e '2 + nil'
-e:1:in `+': nil can't be coerced into Fixnum (TypeError)
        from -e:1:in `<main>'
$ ruby -e 'nil + 2'
-e:1:in `<main>': undefined method `+' for nil:NilClass (NoMethodError)

Kind regards

robert


-- 
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/