Project

General

Profile

Bug #2830

Some methods raise ArgumentError instead of TypeError

Added by marcandre (Marc-Andre Lafortune) over 9 years ago. Updated about 8 years ago.

Status:
Closed
Priority:
Normal
Target version:
ruby -v:
ruby 1.9.2dev (2010-03-02 trunk 26792) [x86_64-darwin10.2.0]
Backport:
[ruby-core:28395]

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

History

#1

Updated by matz (Yukihiro Matsumoto) over 9 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.
#2

Updated by mame (Yusuke Endoh) over 9 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

#3

Updated by naruse (Yui NARUSE) over 9 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

#4

Updated by marcandre (Marc-Andre Lafortune) over 9 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

Also available in: Atom PDF