Project

General

Profile

Actions

Bug #2830

closed

Some methods raise ArgumentError instead of TypeError

Bug #2830: Some methods raise ArgumentError instead of TypeError

Added by marcandre (Marc-Andre Lafortune) over 15 years ago. Updated over 14 years ago.

Status:
Closed
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

Updated by matz (Yukihiro Matsumoto) over 15 years ago Actions #1

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 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 15 years ago Actions #2

=begin
Hi,

2010/3/3 Yukihiro Matsumoto :

|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

=end

Updated by naruse (Yui NARUSE) over 15 years ago Actions #3

=begin
Hi,

(2010/03/03 20:18), Yusuke ENDOH wrote:

2010/3/3 Yukihiro Matsumoto :

|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

=end

Updated by marcandre (Marc-Andre Lafortune) over 15 years ago Actions #4

  • 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

Actions

Also available in: PDF Atom