Hi,

2010/2/28 Kenta Murata <muraken / gmail.com>:
> I've merged and committed patches of platform-independent Math to
> ruby-trunk and rubyspec-master.

Great!

A couple of things about the new exception class:

1) I just noticed that the new Exception class is Math::DomainError,
and not simply DomainError as I thought.

No other Exception class belongs to a Module/Class (well, except from
Errno), even though some are only raise by a specific class (e.g.
ThreadError, FiberError). Moreover, there might be other methods than
Math:: methods that raise it (among others, maybe Float#/ will raise
it). For these reasons, I feel it should not be scoped.

2) Although I suggested that DomainError could be a subclass of
ArgumentError, I feel now, after reviewing the exception classes, that
it should not, in the same way that
ZeroDivisionError/TypeError/IndexError/KeyError aren't.
Moreover, maybe one day we'll want Float#log, say, and then it will
clearly make no sense to be an ArgumentError.

3) Finally, I can not see when a ZeroDivisionError should not be
considered to also be a DomainError, so should we should have
ZeroDivisionError < DomainError.

What do you think of the following patch I propose?

diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index d56d42c..1e18dbe 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -1234,7 +1234,7 @@ RUBY_EXTERN VALUE rb_eNameError;
 RUBY_EXTERN VALUE rb_eSyntaxError;
 RUBY_EXTERN VALUE rb_eLoadError;

-RUBY_EXTERN VALUE rb_eMathDomainError;
+RUBY_EXTERN VALUE rb_eDomainError;

 RUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr;

diff --git a/math.c b/math.c
index d4251df..0232be9 100644
--- a/math.c
+++ b/math.c
@@ -16,7 +16,6 @@
 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))

 VALUE rb_mMath;
-VALUE rb_eMathDomainError;

 extern VALUE rb_to_float(VALUE val);
 #define Need_Float(x) do {if (TYPE(x) != T_FLOAT) {(x) =
rb_to_float(x);}} while(0)
@@ -26,7 +25,7 @@ extern VALUE rb_to_float(VALUE val);
 } while (0)

 #define domain_error(msg) \
-    rb_raise(rb_eMathDomainError, "Numerical argument is out of
domain - " #msg);
+    rb_raise(rb_eDomainError, "Numerical argument is out of domain - " #msg);

 /*
  *  call-seq:
@@ -746,7 +745,6 @@ void
 Init_Math(void)
 {
     rb_mMath = rb_define_module("Math");
-    rb_eMathDomainError = rb_define_class_under(rb_mMath,
"DomainError", rb_eArgError);

 #ifdef M_PI
     rb_define_const(rb_mMath, "PI", DBL2NUM(M_PI));
diff --git a/numeric.c b/numeric.c
index 02a3da6..b27bb71 100644
--- a/numeric.c
+++ b/numeric.c
@@ -104,6 +104,7 @@ VALUE rb_cFloat;
 VALUE rb_cInteger;
 VALUE rb_cFixnum;

+VALUE rb_eDomainError;
 VALUE rb_eZeroDivError;
 VALUE rb_eFloatDomainError;

@@ -3218,7 +3219,8 @@ Init_Numeric(void)
     id_to_i = rb_intern("to_i");
     id_eq = rb_intern("==");

-    rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eStandardError);
+    rb_eDomainError = rb_define_class("DomainError", rb_eArgError);
+    rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eDomainError);
     rb_eFloatDomainError = rb_define_class("FloatDomainError", rb_eRangeError);
     rb_cNumeric = rb_define_class("Numeric", rb_cObject);