summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--eval_error.ci12
-rw-r--r--eval_intern.h2
-rw-r--r--eval_method.ci4
-rw-r--r--proc.c29
5 files changed, 51 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index b4da1d5f93..f1bf36d231 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+Tue Dec 18 07:56:57 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * proc.c (rb_obj_public_method): Object#public_method to retrieve
+ public method object.
+
+ * proc.c (rb_mod_public_instance_method): Module#public_instance_method
+ to retrieve public instance method from class / module.
+
+ * proc.c (mnew): visibility check added.
+
+ * eval_error.ci (rb_print_undef): add rb_ prefix.
+
+ * eval_error.ci (rb_print_undef): add visibility in the error
+ message.
+
Tue Dec 18 05:54:26 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
* lib/Env.rb, lib/base64.rb, lib/importenv.rb, lib/eregex.rb: removed.
diff --git a/eval_error.ci b/eval_error.ci
index 210dce073d..94fb18029d 100644
--- a/eval_error.ci
+++ b/eval_error.ci
@@ -207,9 +207,17 @@ ruby_error_print(void)
}
void
-print_undef(VALUE klass, ID id)
+rb_print_undef(VALUE klass, ID id, int scope)
{
- rb_name_error(id, "undefined method `%s' for %s `%s'",
+ char *v;
+
+ switch (scope) {
+ default:
+ case NOEX_PUBLIC: v = ""; break;
+ case NOEX_PRIVATE: v = " private"; break;
+ case NOEX_PROTECTED: v = " protected"; break;
+ }
+ rb_name_error(id, "undefined%s method `%s' for %s `%s'", v,
rb_id2name(id),
(TYPE(klass) == T_MODULE) ? "module" : "class",
rb_class2name(klass));
diff --git a/eval_intern.h b/eval_intern.h
index 61164de9a9..15202fa2f8 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -204,7 +204,7 @@ VALUE rb_make_exception _((int argc, VALUE *argv));
NORETURN(void rb_fiber_start(void));
NORETURN(void rb_raise_jump _((VALUE)));
-NORETURN(void print_undef _((VALUE, ID)));
+NORETURN(void rb_print_undef _((VALUE, ID, int)));
NORETURN(void vm_localjump_error(const char *, VALUE, int));
NORETURN(void vm_jump_tag_but_local_jump(int, VALUE));
diff --git a/eval_method.ci b/eval_method.ci
index 8ebe252ee4..94b39f04b1 100644
--- a/eval_method.ci
+++ b/eval_method.ci
@@ -385,7 +385,7 @@ rb_export_method(VALUE klass, ID name, ID noex)
fbody = search_method(rb_cObject, name, &origin);
}
if (!fbody || !fbody->nd_body) {
- print_undef(klass, name);
+ rb_print_undef(klass, name, 0);
}
if (fbody->nd_body->nd_noex != noex) {
if (klass == origin) {
@@ -573,7 +573,7 @@ rb_alias(VALUE klass, ID name, ID def)
}
}
if (!orig_fbody || !orig_fbody->nd_body) {
- print_undef(klass, def);
+ rb_print_undef(klass, def, 0);
}
if (FL_TEST(klass, FL_SINGLETON)) {
singleton = rb_iv_get(klass, "__attached__");
diff --git a/proc.c b/proc.c
index d2bf571393..0bc3e99963 100644
--- a/proc.c
+++ b/proc.c
@@ -638,7 +638,7 @@ bm_mark(struct METHOD *data)
NODE *rb_get_method_body(VALUE klass, ID id, ID *idp);
static VALUE
-mnew(VALUE klass, VALUE obj, ID id, VALUE mclass)
+mnew(VALUE klass, VALUE obj, ID id, VALUE mclass, int scope)
{
VALUE method;
NODE *body;
@@ -648,7 +648,10 @@ mnew(VALUE klass, VALUE obj, ID id, VALUE mclass)
again:
if ((body = rb_get_method_body(klass, id, 0)) == 0) {
- print_undef(rclass, oid);
+ rb_print_undef(rclass, oid, 0);
+ }
+ if (scope && (body->nd_noex & NOEX_MASK) != NOEX_PUBLIC) {
+ rb_print_undef(rclass, oid, (body->nd_noex & NOEX_MASK));
}
klass = body->nd_clss;
@@ -864,7 +867,13 @@ method_owner(VALUE obj)
VALUE
rb_obj_method(VALUE obj, VALUE vid)
{
- return mnew(CLASS_OF(obj), obj, rb_to_id(vid), rb_cMethod);
+ return mnew(CLASS_OF(obj), obj, rb_to_id(vid), rb_cMethod, Qfalse);
+}
+
+VALUE
+rb_obj_public_method(VALUE obj, VALUE vid)
+{
+ return mnew(CLASS_OF(obj), obj, rb_to_id(vid), rb_cMethod, Qtrue);
}
/*
@@ -900,9 +909,15 @@ rb_obj_method(VALUE obj, VALUE vid)
*/
static VALUE
-rb_mod_method(VALUE mod, VALUE vid)
+rb_mod_instance_method(VALUE mod, VALUE vid)
+{
+ return mnew(mod, Qundef, rb_to_id(vid), rb_cUnboundMethod, Qfalse);
+}
+
+static VALUE
+rb_mod_public_instance_method(VALUE mod, VALUE vid)
{
- return mnew(mod, Qundef, rb_to_id(vid), rb_cUnboundMethod);
+ return mnew(mod, Qundef, rb_to_id(vid), rb_cUnboundMethod, Qtrue);
}
/*
@@ -1518,6 +1533,7 @@ Init_Proc(void)
rb_define_method(rb_cMethod, "owner", method_owner, 0);
rb_define_method(rb_cMethod, "unbind", method_unbind, 0);
rb_define_method(rb_mKernel, "method", rb_obj_method, 1);
+ rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1);
/* UnboundMethod */
rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject);
@@ -1535,7 +1551,8 @@ Init_Proc(void)
rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
/* Module#*_method */
- rb_define_method(rb_cModule, "instance_method", rb_mod_method, 1);
+ rb_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1);
+ rb_define_method(rb_cModule, "public_instance_method", rb_mod_public_instance_method, 1);
rb_define_private_method(rb_cModule, "define_method", rb_mod_define_method, -1);
/* Kernel */