[前][次][番号順一覧][スレッド一覧]

ruby-changes:11559

From: akr <ko1@a...>
Date: Thu, 16 Apr 2009 23:17:32 +0900 (JST)
Subject: [ruby-changes:11559] Ruby:r23192 (trunk): * class.c (rb_define_method_id): use rb_define_notimplement_method_id

akr	2009-04-16 23:17:14 +0900 (Thu, 16 Apr 2009)

  New Revision: 23192

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=23192

  Log:
    * class.c (rb_define_method_id): use rb_define_notimplement_method_id
      if rb_f_notimplement is given.
      (rb_define_protected_method): ditto.
      (rb_define_private_method): ditto.
      (rb_define_method): use rb_define_method_id.
    * include/ruby/intern.h (rb_f_notimplement): declared.
      (rb_define_notimplement_method_id): declared.
    
    * proc.c (method_inspect): show not-implemented.
    
    * vm_method.c (notimplement_body): new variable.
      (rb_notimplement_body_p): new function.
      (rb_method_boundp): return false if not implemented.
      (rb_f_notimplement): new function.
      (rb_define_notimplement_method_id): new function.
    
    * process.c (rb_f_fork): use rb_f_notimplement if not implemented.
    
    * file.c (rb_file_s_lchmod): use rb_f_notimplement if not implemented.

  Added files:
    trunk/test/ruby/test_notimp.rb
  Modified files:
    trunk/ChangeLog
    trunk/NEWS
    trunk/class.c
    trunk/file.c
    trunk/include/ruby/intern.h
    trunk/proc.c
    trunk/process.c
    trunk/vm_method.c

Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 23191)
+++ include/ruby/intern.h	(revision 23192)
@@ -275,6 +275,8 @@
 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);
+VALUE rb_f_notimplement(int argc, VALUE *argv, VALUE obj);
 void rb_interrupt(void);
 VALUE rb_apply(VALUE, ID, VALUE);
 void rb_backtrace(void);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 23191)
+++ ChangeLog	(revision 23192)
@@ -1,3 +1,26 @@
+Thu Apr 16 23:09:03 2009  Tanaka Akira  <akr@f...>
+
+	* class.c (rb_define_method_id): use rb_define_notimplement_method_id
+	  if rb_f_notimplement is given.
+	  (rb_define_protected_method): ditto.
+	  (rb_define_private_method): ditto.
+	  (rb_define_method): use rb_define_method_id.
+
+	* include/ruby/intern.h (rb_f_notimplement): declared.
+	  (rb_define_notimplement_method_id): declared.
+
+	* proc.c (method_inspect): show not-implemented.
+
+	* vm_method.c (notimplement_body): new variable.
+	  (rb_notimplement_body_p): new function.
+	  (rb_method_boundp): return false if not implemented.
+	  (rb_f_notimplement): new function.
+	  (rb_define_notimplement_method_id): new function.
+
+	* process.c (rb_f_fork): use rb_f_notimplement if not implemented.
+
+	* file.c (rb_file_s_lchmod): use rb_f_notimplement if not implemented.
+
 Wed Apr 15 20:24:49 2009  Yusuke Endoh  <mame@t...>
 
 	* array.c (rb_ary_flatten): flatten(0) works as Array#dup.
Index: proc.c
===================================================================
--- proc.c	(revision 23191)
+++ proc.c	(revision 23192)
@@ -1616,6 +1616,9 @@
     }
     rb_str_buf_cat2(str, sharp);
     rb_str_append(str, rb_id2str(data->oid));
+    if (rb_notimplement_body_p(data->body)) {
+        rb_str_buf_cat2(str, " (not-implemented)");
+    }
     rb_str_buf_cat2(str, ">");
 
     return str;
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 23191)
+++ vm_method.c	(revision 23192)
@@ -24,6 +24,8 @@
 #define ruby_running (GET_VM()->running)
 /* int ruby_running = 0; */
 
+static NODE *notimplement_body = 0;
+
 void
 rb_clear_cache(void)
 {
@@ -414,6 +416,12 @@
 }
 
 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;
@@ -422,6 +430,8 @@
 	if (ex && (method->nd_noex & NOEX_PRIVATE)) {
 	    return Qfalse;
 	}
+        if (rb_notimplement_body_p(method->nd_body))
+           return Qfalse;
 	return Qtrue;
     }
     return Qfalse;
@@ -811,6 +821,18 @@
     return mod;
 }
 
+VALUE
+rb_f_notimplement(int argc, VALUE *argv, VALUE obj)
+{
+    rb_notimplement();
+}
+
+void
+rb_define_notimplement_method_id(VALUE mod, ID id, int noex)
+{
+    rb_add_method(mod, id, notimplement_body, noex);
+}
+
 static void
 secure_visibility(VALUE self)
 {
@@ -1137,5 +1159,8 @@
     singleton_removed = rb_intern("singleton_method_removed");
     undefined = rb_intern("method_undefined");
     singleton_undefined = rb_intern("singleton_method_undefined");
+
+    rb_global_variable(&notimplement_body);
+    notimplement_body = NEW_CFUNC(rb_f_notimplement, -1);
 }
 
Index: class.c
===================================================================
--- class.c	(revision 23191)
+++ class.c	(revision 23192)
@@ -807,25 +807,36 @@
 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_f_notimplement)
+        rb_define_notimplement_method_id(klass, name, NOEX_PUBLIC);
+    else
+        rb_add_method(klass, name, NEW_CFUNC(func,argc), 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);
+    rb_define_method_id(klass, rb_intern(name), func, argc);
 }
 
 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_f_notimplement)
+        rb_define_notimplement_method_id(klass, id, NOEX_PROTECTED);
+    else
+        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_f_notimplement)
+        rb_define_notimplement_method_id(klass, id, NOEX_PRIVATE);
+    else
+        rb_add_method(klass, id, NEW_CFUNC(func, argc), NOEX_PRIVATE);
 }
 
 void
Index: process.c
===================================================================
--- process.c	(revision 23191)
+++ process.c	(revision 23192)
@@ -2601,10 +2601,10 @@
  *  fork doesn't copy other threads.
  */
 
+#if defined(HAVE_FORK) && !defined(CANNOT_FORK_WITH_PTHREAD)
 static VALUE
 rb_f_fork(VALUE obj)
 {
-#if defined(HAVE_FORK) && !defined(CANNOT_FORK_WITH_PTHREAD)
     rb_pid_t pid;
 
     rb_secure(2);
@@ -2630,12 +2630,11 @@
       default:
 	return PIDT2NUM(pid);
     }
+}
 #else
-    rb_notimplement();
+#define rb_f_fork rb_f_notimplement
 #endif
-}
 
-
 /*
  *  call-seq:
  *     Process.exit!(fixnum=-1)
Index: NEWS
===================================================================
--- NEWS	(revision 23191)
+++ NEWS	(revision 23192)
@@ -47,6 +47,11 @@
     * extended methods:
       * string[regexp, name] is supported for named capture.
 
+  * Kernel
+    * extended methods:
+      * respond_to? returns false for not-implemented methods
+        such as fork on Windows.
+
 * rss
 
   * 0.2.4 -> 0.2.5
Index: test/ruby/test_notimp.rb
===================================================================
--- test/ruby/test_notimp.rb	(revision 0)
+++ test/ruby/test_notimp.rb	(revision 23192)
@@ -0,0 +1,64 @@
+require 'test/unit'
+require 'tmpdir'
+
+class TestNotImplement < Test::Unit::TestCase
+  def test_respond_to_fork
+    assert_includes(Process.methods, :fork)
+    if /linux/ =~ RUBY_PLATFORM
+      assert_equal(true, Process.respond_to?(:fork))
+    end
+  end
+
+  def test_respond_to_lchmod
+    assert_includes(File.methods, :lchmod)
+    if /linux/ =~ RUBY_PLATFORM
+      assert_equal(false, File.respond_to?(:lchmod))
+    end
+    if /freebsd/ =~ RUBY_PLATFORM
+      assert_equal(true, File.respond_to?(:lchmod))
+    end
+  end
+
+  def test_call_fork
+    if Process.respond_to?(:fork)
+      assert_nothing_raised {
+        pid = fork {}
+        Process.wait pid
+      }
+    end
+  end
+
+  def test_call_lchmod
+    if File.respond_to?(:lchmod)
+      Dir.mktmpdir {|d|
+        f = "#{d}/f"
+        g = "#{d}/g"
+        File.open(f, "w") {}
+        File.symlink f, g
+        newmode = 0444
+        File.lchmod newmode, "#{d}/g"
+        snew = File.lstat(g)
+        assert_equal(newmode, snew.mode & 0777)
+      }
+    end
+  end
+
+  def test_method_inspect_fork
+    m = Process.method(:fork)
+    if Process.respond_to?(:fork)
+      assert_not_match(/not-implemented/, m.inspect)
+    else
+      assert_match(/not-implemented/, m.inspect)
+    end
+  end
+
+  def test_method_inspect_lchmod
+    m = File.method(:lchmod)
+    if File.respond_to?(:lchmod)
+      assert_not_match(/not-implemented/, m.inspect)
+    else
+      assert_match(/not-implemented/, m.inspect)
+    end
+  end
+
+end
Index: file.c
===================================================================
--- file.c	(revision 23191)
+++ file.c	(revision 23192)
@@ -1926,12 +1926,7 @@
     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 rb_f_notimplement
 #endif
 
 struct chown_args {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]