Bug #2830
Some methods raise ArgumentError instead of TypeError
| Status: | Closed | Start date: | 03/02/2010 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | % Done: | 100% |
||
| Category: | core | |||
| Target version: | 1.9.2 | |||
| ruby -v: | ruby 1.9.2dev (2010-03-02 trunk 26792) [x86_64-darwin10.2.0] |
Description
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");
}
}
Associated revisions
* complex.c (nucomp_real_check): raise TypeError instead of ArgumentError
when argument is not a real as expected [ruby-core:28395]
* rational.c (nurat_int_check): ditto (for integers)
History
Updated by matz (Yukihiro Matsumoto) about 2 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) about 2 years ago
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>
Updated by naruse (Yui NARUSE) about 2 years ago
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>
Updated by marcandre (Marc-Andre Lafortune) about 2 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
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.