[lnkForumImage]
TotalShareware - Download Free Software

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


 

Artur Merke

11/10/2003 4:35:00 PM

10 Answers

ts

11/10/2003 4:42:00 PM

0

>>>>> "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

Robert Klemme

11/10/2003 4:45:00 PM

0


"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

Simon Strandgaard

11/10/2003 4:58:00 PM

0

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>

Artur Merke

11/11/2003 11:50:00 AM

0

Robert Klemme

11/11/2003 1:20:00 PM

0


"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

Josef 'Jupp' Schugt

11/17/2003 9:47:00 PM

0

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? / ___| |___

Artur Merke

11/19/2003 9:47:00 AM

0

Robert Klemme

11/19/2003 5:26:00 PM

0


"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? / ___| |___
> >
> >
>

matz

11/19/2003 6:13:00 PM

0

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.


Josef 'Jupp' Schugt

11/20/2003 1:32:00 PM

0

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? / ___| |___