* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23192 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
bded3bb726
commit
8b27d153d2
23
ChangeLog
23
ChangeLog
@ -1,3 +1,26 @@
|
|||||||
|
Thu Apr 16 23:09:03 2009 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* 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@tsg.ne.jp>
|
Wed Apr 15 20:24:49 2009 Yusuke Endoh <mame@tsg.ne.jp>
|
||||||
|
|
||||||
* array.c (rb_ary_flatten): flatten(0) works as Array#dup.
|
* array.c (rb_ary_flatten): flatten(0) works as Array#dup.
|
||||||
|
5
NEWS
5
NEWS
@ -47,6 +47,11 @@ with all sufficient information, see the ChangeLog file.
|
|||||||
* extended methods:
|
* extended methods:
|
||||||
* string[regexp, name] is supported for named capture.
|
* 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
|
* rss
|
||||||
|
|
||||||
* 0.2.4 -> 0.2.5
|
* 0.2.4 -> 0.2.5
|
||||||
|
19
class.c
19
class.c
@ -807,25 +807,36 @@ rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
|
|||||||
void
|
void
|
||||||
rb_define_method_id(VALUE klass, ID name, VALUE (*func)(ANYARGS), int argc)
|
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
|
void
|
||||||
rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
|
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
|
void
|
||||||
rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
|
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
|
void
|
||||||
rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
|
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
|
void
|
||||||
|
7
file.c
7
file.c
@ -1926,12 +1926,7 @@ rb_file_s_lchmod(int argc, VALUE *argv)
|
|||||||
return LONG2FIX(n);
|
return LONG2FIX(n);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static VALUE
|
#define rb_file_s_lchmod rb_f_notimplement
|
||||||
rb_file_s_lchmod(int argc, VALUE *argv)
|
|
||||||
{
|
|
||||||
rb_notimplement();
|
|
||||||
return Qnil; /* not reached */
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct chown_args {
|
struct chown_args {
|
||||||
|
@ -275,6 +275,8 @@ int rb_method_basic_definition_p(VALUE, ID);
|
|||||||
VALUE rb_eval_cmd(VALUE, VALUE, int);
|
VALUE rb_eval_cmd(VALUE, VALUE, int);
|
||||||
int rb_obj_respond_to(VALUE, ID, int);
|
int rb_obj_respond_to(VALUE, ID, int);
|
||||||
int rb_respond_to(VALUE, ID);
|
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);
|
void rb_interrupt(void);
|
||||||
VALUE rb_apply(VALUE, ID, VALUE);
|
VALUE rb_apply(VALUE, ID, VALUE);
|
||||||
void rb_backtrace(void);
|
void rb_backtrace(void);
|
||||||
|
3
proc.c
3
proc.c
@ -1616,6 +1616,9 @@ method_inspect(VALUE method)
|
|||||||
}
|
}
|
||||||
rb_str_buf_cat2(str, sharp);
|
rb_str_buf_cat2(str, sharp);
|
||||||
rb_str_append(str, rb_id2str(data->oid));
|
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, ">");
|
rb_str_buf_cat2(str, ">");
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
|
@ -2601,10 +2601,10 @@ rb_fork(int *status, int (*chfunc)(void*), void *charg, VALUE fds)
|
|||||||
* fork doesn't copy other threads.
|
* fork doesn't copy other threads.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(HAVE_FORK) && !defined(CANNOT_FORK_WITH_PTHREAD)
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_f_fork(VALUE obj)
|
rb_f_fork(VALUE obj)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_FORK) && !defined(CANNOT_FORK_WITH_PTHREAD)
|
|
||||||
rb_pid_t pid;
|
rb_pid_t pid;
|
||||||
|
|
||||||
rb_secure(2);
|
rb_secure(2);
|
||||||
@ -2630,11 +2630,10 @@ rb_f_fork(VALUE obj)
|
|||||||
default:
|
default:
|
||||||
return PIDT2NUM(pid);
|
return PIDT2NUM(pid);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
rb_notimplement();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
#define rb_f_fork rb_f_notimplement
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
|
64
test/ruby/test_notimp.rb
Normal file
64
test/ruby/test_notimp.rb
Normal file
@ -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
|
25
vm_method.c
25
vm_method.c
@ -24,6 +24,8 @@ static struct cache_entry cache[CACHE_SIZE];
|
|||||||
#define ruby_running (GET_VM()->running)
|
#define ruby_running (GET_VM()->running)
|
||||||
/* int ruby_running = 0; */
|
/* int ruby_running = 0; */
|
||||||
|
|
||||||
|
static NODE *notimplement_body = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_clear_cache(void)
|
rb_clear_cache(void)
|
||||||
{
|
{
|
||||||
@ -413,6 +415,12 @@ rb_export_method(VALUE klass, ID name, ID noex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_notimplement_body_p(NODE *method)
|
||||||
|
{
|
||||||
|
return method == notimplement_body ? Qtrue : Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rb_method_boundp(VALUE klass, ID id, int ex)
|
rb_method_boundp(VALUE klass, ID id, int ex)
|
||||||
{
|
{
|
||||||
@ -422,6 +430,8 @@ rb_method_boundp(VALUE klass, ID id, int ex)
|
|||||||
if (ex && (method->nd_noex & NOEX_PRIVATE)) {
|
if (ex && (method->nd_noex & NOEX_PRIVATE)) {
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
}
|
}
|
||||||
|
if (rb_notimplement_body_p(method->nd_body))
|
||||||
|
return Qfalse;
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
@ -811,6 +821,18 @@ rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
|
|||||||
return mod;
|
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
|
static void
|
||||||
secure_visibility(VALUE self)
|
secure_visibility(VALUE self)
|
||||||
{
|
{
|
||||||
@ -1137,5 +1159,8 @@ Init_eval_method(void)
|
|||||||
singleton_removed = rb_intern("singleton_method_removed");
|
singleton_removed = rb_intern("singleton_method_removed");
|
||||||
undefined = rb_intern("method_undefined");
|
undefined = rb_intern("method_undefined");
|
||||||
singleton_undefined = rb_intern("singleton_method_undefined");
|
singleton_undefined = rb_intern("singleton_method_undefined");
|
||||||
|
|
||||||
|
rb_global_variable(¬implement_body);
|
||||||
|
notimplement_body = NEW_CFUNC(rb_f_notimplement, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user