@mame (Yusuke Endoh) It seems that you were not aware of the fact that the documentation is wrong. And I hope you share with me the idea that we want the documentation to be correct. I think the reason why there was a mistake in the documentation, and why you have not noticed it, is either because the specification is ad hoc or it was not implemented in the way it was intended or in the way people would normally expect. I believe this has to be solved in some way.
I can say that the current behavior is counter-intuitive. Even though Integer
class is not a subclass of Rational
class, coercion relation indicates that whatever can be interpreted as an Integer
can be interpreted as a Rational
but not vice versa. And I think people would normally expect whatever is interpretable by Kernel#Integer
is interpretable by Kernel#Rational
.
A use case that I can think of where this becomes relevant is an arithmetic program in which some string (from user input or from some data) is attempted to be interpreted using methods like Kernel#Rational
or Kernel#Integer
one after another (avoiding the use of methods like eval
in fear of malicious code). Such program may attempt interpretation of a string by Kernel#Rational
, and if it succeeds, go on to attempt interpretation by Kernel#Integer
to see if the interpretation can be further narrowed down. However, if a non-decimal integer string is passed to Kernel#Rational
and an error is raised, such program would give up attempting interpretation by Kernel#Integer
, even though it would succeed, and that input string would be thrown away.
Even more strange is the fact that, in case of hexadecimal 0x
(but not with other 0
prefixes), it becomes interpretable again by Kernel#Float
. This is a real mess.
Integer("0x10") # => 16
Rational("0x10") # !> ArgumentError
Float("0x10") # => 16.0