In trying to convert a string to an integer, I found this passage in the
ruby documentation: http://dev.rubycentral.com/ref/
···
-------------
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.
-------------
That description seems complete. It talks about edge cases, and what
happens, and that the method doesn't throw an exception. Then I found
this passage:
-----------
Integer( arg ) -> anInteger
Converts arg to a Fixnum or Bignum. Numeric types are converted directly
(with floating point numbers being truncated). If arg is a String,
leading radix indicators (0, 0b, and 0x) are honored. This behavior is
different from that of String#to_i.
------------
In that description, there is no mention of exceptions that can be
thrown, but when I try the Integer() method, this is the output:
irb(main):002:0> Integer("10")
=> 10
irb(main):003:0> Integer("10abc")
ArgumentError: invalid value for Integer: "10abc"
from (irb):3:in `Integer'
from (irb):3
irb(main):004:0> Integer("hello")
ArgumentError: invalid value for Integer: "hello"
from (irb):4:in `Integer'
from (irb):4
irb(main):005:0>
So, it seems pretty clear that the Integer() method can throw an
ArgumentError exception, and I'm wondering why the docs don't mention
what exceptions Integer() throws? Is that typical of the docs? If it
doesn't say "no exceptions are thrown", should I assume it can throw
some as yet unidentified exception?
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.
-------------
That description seems complete. It talks about edge cases, and what
happens, and that the method doesn't throw an exception. Then I found
this passage:
-----------
Integer( arg ) -> anInteger
Converts arg to a Fixnum or Bignum. Numeric types are converted directly
(with floating point numbers being truncated). If arg is a String,
leading radix indicators (0, 0b, and 0x) are honored. This behavior is
different from that of String#to_i.
------------
In that description, there is no mention of exceptions that can be
thrown, but when I try the Integer() method, this is the output:
irb(main):002:0> Integer("10")
=> 10
irb(main):003:0> Integer("10abc")
ArgumentError: invalid value for Integer: "10abc"
from (irb):3:in `Integer'
from (irb):3
irb(main):004:0> Integer("hello")
ArgumentError: invalid value for Integer: "hello"
from (irb):4:in `Integer'
from (irb):4
irb(main):005:0>
So, it seems pretty clear that the Integer() method can throw an
ArgumentError exception, and I'm wondering why the docs don't mention
what exceptions Integer() throws? Is that typical of the docs? If it
doesn't say "no exceptions are thrown", should I assume it can throw
some as yet unidentified exception?
The documentation isn't perfect. There is information about contributing
to Ruby documentation at www.ruby-doc.org.
It has been my observation that the Ruby style is to avoid the use
of exceptions as part of the expected behavior of a method. What I mean
is that, in general, if you provide arguments to a method that meet the
method's pre-conditions then you will get back a result with no exception
being raised. If you provide arguments that *don't* meet the
pre-conditions of a method, well then you may or may not get an exception
but it is really your problem in either case because you violated the
pre-condition and all bets are off.
Test driven development really puts the burden on the caller to provide
the correct arguments and methods are often written with that explicit
expectation, which tends to reduce the amount of argument checking that
is done in methods.
When exceptions are explicitly part of the behavior of a method then I,
of course, think their use should be documented.
I'd be interested in other perspectives on best practices with respect
to exceptions and argument checking in API/class design.
I think this depends somewhat on your definition of an argument.
If I do "0101110".to_i(2), then clearly 2 is an argument. But is "0101110"? Technically, no, it is the receiver. In Ruby's duck typed world where multiple, same named methods do different things depending
···
on class, then it kindof is an argument. Dan Gary Wright wrote:
Looks like it could TypeError and NoMethodError as well...
So the docs don't "document" which exceptions can be thrown by a method?
The documentation isn't perfect. There is information about contributing
to Ruby documentation at www.ruby-doc.org.
It has been my observation that the Ruby style is to avoid the use
of exceptions as part of the expected behavior of a method. What I mean
is that, in general, if you provide arguments to a method that meet the
method's pre-conditions then you will get back a result with no exception
being raised. If you provide arguments that *don't* meet the
pre-conditions of a method, well then you may or may not get an exception
but it is really your problem in either case because you violated the
pre-condition and all bets are off.
Test driven development really puts the burden on the caller to provide
the correct arguments and methods are often written with that explicit
expectation, which tends to reduce the amount of argument checking that
is done in methods.
When exceptions are explicitly part of the behavior of a method then I,
of course, think their use should be documented.
I'd be interested in other perspectives on best practices with respect
to exceptions and argument checking in API/class design.
Integer( arg ) -> anInteger
....If arg is a String
Gary Wright wrote:
being raised. If you provide arguments that *don't* meet the
pre-conditions of a method, well then you may or may not get an
exception
but it is really your problem in either case because you violated the
pre-condition and all bets are off.
I gave Integer() a string and it threw an exception.
But the current state of an object can certainly be part of the pre-condition for a method. Pre-conditions aren't entirely about the arguments to a method.
Gary Wright
···
On Mar 11, 2007, at 8:19 PM, Daniel Finnie wrote:
I think this depends somewhat on your definition of an argument.
If I do "0101110".to_i(2), then clearly 2 is an argument. But is "0101110"? Technically, no, it is the receiver. In Ruby's duck typed world where multiple, same named methods do different things depending on class, then it kindof is an argument.
Alle lunedì 12 marzo 2007, 7stud 7stud ha scritto:
The docs wrote:
>>Integer( arg ) -> anInteger
>>....If arg is a String
Gary Wright wrote:
> being raised. If you provide arguments that *don't* meet the
> pre-conditions of a method, well then you may or may not get an
> exception
> but it is really your problem in either case because you violated the
> pre-condition and all bets are off.
I gave Integer() a string and it threw an exception.
A quick look at the documentation has lead me to the following considerations:
There *are* some places where documentation about exceptions raised is truly
missing (examples: File.read => LoadError if file doesn't exist; File.write
=> SystemCallError if file isn't open for writing, and, of course Integer()).
These methods, in my opinion, need to be better documented.
Some situations are implicitly assumed to throw exceptions:
- passing a method an argument of a type different from the one required (for
example, a string to Fixnum#to_s), raises a TypeError exception
- passing a method an argument which is of the correct type, but which doesn't
fulfill al the prerequisites (for instance, passing an integer greater than
36 to Fixnum#to_s), raises an ArgumentError exception
- a method which should do some parsing (for instance Regexp.new or YAML.load)
raises an exception if the string doesn't contain valid code. The kind of
exception varies, though (Regexp.new raises a RegexpError while YAML.load
raises ArgumentError)
I muddled up a specific response to you about Integer with some
more general observations about exceptions and Ruby. Sorry I wasn't
clear:
1) Ruby documentation isn't perfect. You found a problem.
2) There are methods (i.e. Integer()) where exceptions are part
of the expected behavior of the method and they *should* be
documented. If they aren't, that is a bug not a feature.
3) Most Ruby methods don't say anything about exceptions because
exceptions are not part of the API of most Ruby methods. There
is an overall assumption that if you call a method without meeting
the pre-conditions then the behavior (including the raising of
exceptions) is undefined.
4) Pre-conditions should be clearly described by the documentation.
Gary Wright
···
On Mar 11, 2007, at 11:20 PM, 7stud 7stud wrote:
The docs wrote:
Integer( arg ) -> anInteger
....If arg is a String
Gary Wright wrote:
being raised. If you provide arguments that *don't* meet the
pre-conditions of a method, well then you may or may not get an
exception
but it is really your problem in either case because you violated the
pre-condition and all bets are off.
I gave Integer() a string and it threw an exception.
I gave Integer() a string and it threw an exception.
I muddled up a specific response to you about Integer with some
more general observations about exceptions and Ruby. Sorry I wasn't
clear:
1) Ruby documentation isn't perfect. You found a problem.
2) There are methods (i.e. Integer()) where exceptions are part
of the expected behavior of the method and they *should* be
documented. If they aren't, that is a bug not a feature.
3) Most Ruby methods don't say anything about exceptions because
exceptions are not part of the API of most Ruby methods. There
is an overall assumption that if you call a method without meeting
the pre-conditions then the behavior (including the raising of
exceptions) is undefined.
4) Pre-conditions should be clearly described by the documentation.
Gary Wright
Ok. I was all set to buy the pickaxe book, but then I noticed that
missing documentation, so I decided to look for alternatives. I looked
in "The Ruby Way", and it mentions that Integer() throws an exception
when the string is not of the right format in a section titled something
like "Turning strings into numbers". So it looks like those books would
be good companion texts.