In article [email protected],
Tanaka A. [email protected] writes:
e$B<B9T$9$k$He(B NotImplementedError e$B$K$J$j!"e(Brespond_to? e$B$GD4$Y$ke(B
e$B$H56$K$J$kFC<l$J%a%=%C%I$rF3F~$9$k$N$O$I$&$G$9$+$M!#e(B
undef e$B$_$?$$$J$+$s$8$G!#e(B
e$B<BAu$9$k$H$3$s$J46$8$G$7$g$&$+!#e(B
e$B8D!9$N%a%=%C%I$K$D$$$F$O$H$j$“$($:e(B fork e$B$He(B File.lchmod
e$B$@$1e(B
e$BBP=h$7$F$”$j$^$9!#e(B
GNU/Linux e$B$K$Oe(B lchmod e$B$,$J$$$N$G!"e(BFile.respond_to?(:lchmod)
e$B$Oe(B false e$B$K$J$j!"e(BFile.lchmod e$B$r8F$S=P$9$He(B
NotImplementedError e$B$K$J$j$^$9!#e(B
% ./ruby -ve ’
p File.respond_to?(:lchmod)
File.lchmod(“foo”, 0777)’
ruby 1.9.0 (2008-05-14 revision 16419) [i686-linux]
false
-e:3:in lchmod': lchmod() function is unimplemented on this machine (NotImplementedError) from -e:3:in
’
Index: include/ruby/intern.h
— include/ruby/intern.h (revision 16419)
+++ include/ruby/intern.h (working copy)
@@ -252,6 +252,7 @@ int rb_method_boundp(VALUE, ID, int);
VALUE rb_eval_cmd(VALUE, VALUE, int);
int rb_obj_respond_to(VALUE, ID, int);
int rb_respond_to(VALUE, ID);
+void rb_define_notimplement_method_id(VALUE mod, ID id, int noex);
void rb_interrupt(void);
VALUE rb_apply(VALUE, ID, VALUE);
void rb_backtrace(void);
Index: include/ruby/node.h
— include/ruby/node.h (revision 16419)
+++ include/ruby/node.h (working copy)
@@ -498,6 +498,8 @@ NODE rb_node_newnode(enum node_type,VAL
NODE rb_method_node(VALUE klass, ID id);
int rb_node_arity(NODE* node);
+int rb_notimplement_body_p(NODE*);
+
struct global_entry *rb_global_entry(ID);
VALUE rb_gvar_get(struct global_entry *);
VALUE rb_gvar_set(struct global_entry *, VALUE);
Index: proc.c
— proc.c (revision 16419)
+++ proc.c (working copy)
@@ -935,6 +935,15 @@ method_owner(VALUE obj)
return data->oclass;
}
+static VALUE
+method_notimplemented_p(VALUE obj)
+{
- struct METHOD *data;
-
- Data_Get_Struct(obj, struct METHOD, data);
- return rb_notimplement_body_p(data->body) ? Qtrue : Qfalse;
+}
-
/*
@@ -1763,6 +1772,7 @@ Init_Proc(void)
rb_define_method(rb_cMethod, “name”, method_name, 0);
rb_define_method(rb_cMethod, “owner”, method_owner, 0);
rb_define_method(rb_cMethod, “unbind”, method_unbind, 0);
- rb_define_method(rb_cMethod, “notimplemented?”,
method_notimplemented_p, 0);
rb_define_method(rb_mKernel, “method”, rb_obj_method, 1);
rb_define_method(rb_mKernel, “public_method”, rb_obj_public_method,
1);
@@ -1780,6 +1790,7 @@ Init_Proc(void)
rb_define_method(rb_cUnboundMethod, “name”, method_name, 0);
rb_define_method(rb_cUnboundMethod, “owner”, method_owner, 0);
rb_define_method(rb_cUnboundMethod, “bind”, umethod_bind, 1);
-
rb_define_method(rb_cUnboundMethod, “notimplemented?”,
method_notimplemented_p, 0);
/* Module#*_method */
rb_define_method(rb_cModule, “instance_method”,
rb_mod_instance_method, 1);
Index: class.c
===================================================================
— class.c (revision 16419)
+++ class.c (working copy)
@@ -759,25 +759,40 @@ rb_obj_singleton_methods(int argc, VALUE
void
rb_define_method_id(VALUE klass, ID name, VALUE (*func)(ANYARGS), int
argc)
{
- rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC);
- if (func)
-
rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC);
- else
-
rb_define_notimplement_method_id(klass, name, NOEX_PUBLIC);
}
void
rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS),
int argc)
{
- rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc),
NOEX_PUBLIC);
- ID id = rb_intern(name);
- if (func)
-
rb_add_method(klass, id, NEW_CFUNC(func, argc), NOEX_PUBLIC);
- else
-
rb_define_notimplement_method_id(klass, id, NOEX_PUBLIC);
}
void
rb_define_protected_method(VALUE klass, const char *name, VALUE
(*func)(ANYARGS), int argc)
{
- rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc),
NOEX_PROTECTED);
- ID id = rb_intern(name);
- if (func)
-
rb_add_method(klass, id, NEW_CFUNC(func, argc),
NOEX_PROTECTED);
}
void
rb_define_private_method(VALUE klass, const char *name, VALUE
(*func)(ANYARGS), int argc)
{
- rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc),
NOEX_PRIVATE);
- ID id = rb_intern(name);
- if (func)
-
rb_add_method(klass, id, NEW_CFUNC(func, argc), NOEX_PRIVATE);
- else
-
rb_define_notimplement_method_id(klass, id, NOEX_PRIVATE);
}
void
Index: process.c
— process.c (revision 16419)
+++ process.c (working copy)
@@ -2394,10 +2394,10 @@ rb_fork(int *status, int (chfunc)(void
- fork doesn’t copy other threads.
*/
+#if defined(HAVE_FORK) && !defined(NetBSD)
static VALUE
rb_f_fork(VALUE obj)
{
-#if defined(HAVE_FORK) && !defined(NetBSD)
rb_pid_t pid;
rb_secure(2);
@@ -2423,11 +2423,10 @@ rb_f_fork(VALUE obj)
default:
return PIDT2NUM(pid);
}
+}
#else
- rb_notimplement();
+#define rb_f_fork 0
#endif
-}
-
/*
- call-seq:
Index: eval_method.c
===================================================================
— eval_method.c (revision 16419)
+++ eval_method.c (working copy)
@@ -18,6 +18,8 @@ struct cache_entry { /* method hash tab
static struct cache_entry cache[CACHE_SIZE];
static int ruby_running = 0;
+static NODE *notimplement_body = 0;
+
void
rb_clear_cache(void)
{
@@ -403,6 +405,12 @@ rb_export_method(VALUE klass, ID name, I
}
int
+rb_notimplement_body_p(NODE *method)
+{
- return method == notimplement_body ? Qtrue : Qfalse;
+}
-
+int
rb_method_boundp(VALUE klass, ID id, int ex)
{
NODE *method;
@@ -411,6 +419,8 @@ rb_method_boundp(VALUE klass, ID id, int
if (ex && (method->nd_noex & NOEX_PRIVATE)) {
return Qfalse;
}
+static VALUE
+notimplement_cfunc(VALUE obj)
+{
+void
+rb_define_notimplement_method_id(VALUE mod, ID id, int noex)
+{
- rb_add_method(mod, id, notimplement_body, noex);
+}
-
+static VALUE
+rb_mod_notimplemented_method(int argc, VALUE *argv, VALUE mod)
+{
- int i;
- if (ruby_cbase() == rb_cObject && mod == rb_cObject) {
-
rb_secure(4);
- }
-
- for (i = 0; i < argc; i++) {
-
ID id = rb_to_id(argv[i]);
-
-
if (rb_safe_level() >= 4 && !OBJ_TAINTED(mod)) {
-
rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'",
-
rb_id2name(id));
-
}
-
rb_frozen_class_p(mod);
-
if (id == object_id || id == __send__ || id == init) {
-
rb_warn("notimplementing `%s' may cause serious problem",
rb_id2name(id));
-
}
- rb_define_notimplement_method_id(mod, id, NOEX_PUBLIC);
- }
- return mod;
+}
-
static void
Init_eval_method(void)
{
rb_define_private_method(rb_cModule, “remove_method”,
rb_mod_remove_method, -1);
rb_define_private_method(rb_cModule, “undef_method”,
rb_mod_undef_method, -1);
rb_define_private_method(rb_cModule, “alias_method”,
rb_mod_alias_method, 2);
- rb_global_variable(¬implement_body);
- notimplement_body = NEW_CFUNC(notimplement_cfunc, -1);
- rb_define_private_method(rb_cModule, “notimplemented_method”,
rb_mod_notimplemented_method, -1);
}
Index: file.c
===================================================================
— file.c (revision 16419)
+++ file.c (working copy)
@@ -1901,12 +1901,7 @@ rb_file_s_lchmod(int argc, VALUE *argv)
return LONG2FIX(n);
}
#else
-static VALUE
-rb_file_s_lchmod(int argc, VALUE *argv)
-{
- rb_notimplement();
- return Qnil; /* not reached */
-}
+#define rb_file_s_lchmod 0
#endif
struct chown_args {
Index: test/ruby/test_notimp.rb
— test/ruby/test_notimp.rb (revision 0)
+++ test/ruby/test_notimp.rb (revision 0)
@@ -0,0 +1,33 @@
+require ‘test/unit’
+
+class TestNotImplement < Test::Unit::TestCase
- class C
- notimplemented_method :n
- def x() end
- end
-
- def test_respond_to
- assert_equal(false, C.new.respond_to?(:n))
- assert_equal(true, C.new.respond_to?(:x))
- end
-
- def test_call
- assert_raise(NotImplementedError) { C.new.n }
- assert_nothing_raised { C.new.x }
- end
-
- def test_method
- m = C.new.method(:n)
- assert(m.notimplemented?)
- m = C.new.method(:x)
- assert(!m.notimplemented?)
- end
-
- def test_umethod
- m = C.instance_method(:n)
- assert(m.notimplemented?)
- m = C.instance_method(:x)
- assert(!m.notimplemented?)
- end
-
+end