Bug #2830
closedSome methods raise ArgumentError instead of TypeError
Description
=begin
Some methods of Ruby 1.9 expect integers/reals and call internally nurat_int_value/nurat_int_check. These functions raise an ArgumentError when the argument is not an Integer, instead of a TypeError.
Thus:
42.gcd(:foo) # => ArgumentError, should be TypeError
42.lcm(:foo) # => ditto
42.gcdlcm(:foo) # => ditto
Rational(:foo,1) # => ditto
Note that on the other hand:
Rational(nil, 1) # => TypeError
Rational(:foo) # => TypeError
In a similar fashion:
Complex.rect(nil) # => ArgumentError, should be TypeError
Complex.polar(nil) # => ditto
Unless there is objection, I will commit the following patch (and fix RubySpec):
diff --git a/complex.c b/complex.c
index 214d3a2..6742257 100644
--- a/complex.c
+++ b/complex.c
@@ -377,7 +377,7 @@ nucomp_real_check(VALUE num)
break;
default:
if (!k_numeric_p(num) || !f_real_p(num))
-
rb_raise(rb_eArgError, "not a real");
-
}rb_raise(rb_eTypeError, "not a real");
}
diff --git a/rational.c b/rational.c
index 65d3cf4..f5a6d26 100644
--- a/rational.c
+++ b/rational.c
@@ -419,7 +419,7 @@ nurat_int_check(VALUE num)
break;
default:
if (!k_numeric_p(num) || !f_integer_p(num))
-
rb_raise(rb_eArgError, "not an integer");
-
}rb_raise(rb_eTypeError, "not an integer");
}
=end
Updated by matz (Yukihiro Matsumoto) over 14 years ago
Hi,
In message "Re: [ruby-core:28395] [Bug #2830] Some methods raise ArgumentError instead of TypeError"
on Tue, 2 Mar 2010 13:45:11 +0900, Marc-Andre Lafortune redmine@ruby-lang.org writes:
|Some methods of Ruby 1.9 expect integers/reals and call internally nurat_int_value/nurat_int_check. These functions raise an ArgumentError when the argument is not an Integer, instead of a TypeError.
|Unless there is objection, I will commit the following patch (and fix RubySpec):
Go ahead. I am thinking of making TypeError subclass of
ArgumentError, since every TypeError should occur in relation to any
argument. How do you (guys) think?
matz.
Updated by mame (Yusuke Endoh) over 14 years ago
=begin
Hi,
2010/3/3 Yukihiro Matsumoto matz@ruby-lang.org:
|Some methods of Ruby 1.9 expect integers/reals and call internally nurat_int_value/nurat_int_check. These functions raise an ArgumentError when the argument is not an Integer, instead of a TypeError.
|Unless there is objection, I will commit the following patch (and fix RubySpec):
Agreed.
Go ahead. I am thinking of making TypeError subclass of
ArgumentError, since every TypeError should occur in relation to any
argument. How do you (guys) think?
I really agree with your problem awareness.
Some TypeErrors seem to occur regardless of argument:
0.dup #=> can't dup Fixnum (TypeError)
Class.allocate.superclass #=> uninitialized class (TypeError)
class C
def _dump(x); 1; end
end
Marshal.dump(C.new)' #=> _dump() must return string (TypeError)
We can change them to RuntimeError, etc, of course.
However, I think we need more drastic restructuring of Exception
classification. Even currently, ArgumentError occurs in too many
cases. Rescue'ing ArgumentError is even harmful because it may
hide unexpected ArgumentError.
(http://d.hatena.ne.jp/ku-ma-me/20090423/p1)
And, I said in [ruby-core:28003] TypeError and NoMethodError
should not be distinguished in some cases. It means Exception
does not make hierarchy. Without multiple inheritance, it can be
implemented by representing Exception as mix-in, I think.
So, why don't consider the design carefully towards 2.0?
Thanks,
--
Yusuke ENDOH mame@tsg.ne.jp
=end
Updated by naruse (Yui NARUSE) over 14 years ago
=begin
Hi,
(2010/03/03 20:18), Yusuke ENDOH wrote:
2010/3/3 Yukihiro Matsumoto matz@ruby-lang.org:
|Some methods of Ruby 1.9 expect integers/reals and call internally nurat_int_value/nurat_int_check. These functions raise an ArgumentError when the argument is not an Integer, instead of a TypeError.
|Unless there is objection, I will commit the following patch (and fix RubySpec):Agreed.
I agree with marcandre too.
Go ahead. I am thinking of making TypeError subclass of
ArgumentError, since every TypeError should occur in relation to any
argument. How do you (guys) think?I really agree with your problem awareness.
Some TypeErrors seem to occur regardless of argument:
0.dup #=> can't dup Fixnum (TypeError)
Class.allocate.superclass #=> uninitialized class (TypeError)
class C
def _dump(x); 1; end
end
Marshal.dump(C.new)' #=> _dump() must return string (TypeError)We can change them to RuntimeError, etc, of course.
However, I think we need more drastic restructuring of Exception
classification. Even currently, ArgumentError occurs in too many
cases. Rescue'ing ArgumentError is even harmful because it may
hide unexpected ArgumentError.
(http://d.hatena.ne.jp/ku-ma-me/20090423/p1)And, I said in [ruby-core:28003] TypeError and NoMethodError
should not be distinguished in some cases. It means Exception
does not make hierarchy. Without multiple inheritance, it can be
implemented by representing Exception as mix-in, I think.So, why don't consider the design carefully towards 2.0?
But I fully agree with Yusuke;
This change will be a system wide change.
I think it won't be concluded before 1.9.2 release.
So applying it to trunk should be carefully.
--
NARUSE, Yui naruse@airemix.jp
=end
Updated by marcandre (Marc-Andre Lafortune) over 14 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
This issue was solved with changeset r26805.
Marc-Andre, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
=end