Bug #2830

Some methods raise ArgumentError instead of TypeError

Added by marcandre (Marc-Andre Lafortune) about 2 years ago. Updated about 1 year ago.

[ruby-core:28395]
Status:Closed Start date:03/02/2010
Priority:Normal Due date:
Assignee:marcandre (Marc-Andre Lafortune) % 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

Revision 26805
Added by marcandre (Marc-Andre Lafortune) about 2 years ago

* 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.

Also available in: Atom PDF