From 79a83ed766f00983be558cf6c70b0bacb50d8dc2 Mon Sep 17 00:00:00 2001 From: yui-knk Date: Sun, 15 Nov 2015 13:17:00 +0900 Subject: [PATCH] Add `Method#visibility` and `UnboundMethod#visibility` These method allow us to get visibility from `Method` and `UnboundMethod` object. --- proc.c | 26 ++++++++++++++++++++++++++ test/ruby/test_method.rb | 13 +++++++++++++ 2 files changed, 39 insertions(+) diff --git a/proc.c b/proc.c index 6cbe08c..70dcd08 100644 --- a/proc.c +++ b/proc.c @@ -2558,6 +2558,30 @@ method_super_method(VALUE method) } /* + * call-seq: + * meth.visibility -> symbol + * + * Returns a symbol (:public, :private, or :protected). + */ + +static VALUE +rb_method_visibility(VALUE method) +{ + const struct METHOD *data; + VALUE sym; + + TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); + switch(METHOD_ENTRY_VISI(data->me)) { + case METHOD_VISI_UNDEF: + case METHOD_VISI_PUBLIC: sym = ID2SYM(rb_intern("public")); break; + case METHOD_VISI_PRIVATE: sym = ID2SYM(rb_intern("private")); break; + case METHOD_VISI_PROTECTED: sym = ID2SYM(rb_intern("protected")); break; + default: UNREACHABLE; + } + return sym; +} + +/* * call-seq: * local_jump_error.exit_value -> obj * @@ -2929,6 +2953,7 @@ Init_Proc(void) rb_define_method(rb_cMethod, "source_location", rb_method_location, 0); rb_define_method(rb_cMethod, "parameters", rb_method_parameters, 0); rb_define_method(rb_cMethod, "super_method", method_super_method, 0); + rb_define_method(rb_cMethod, "visibility", rb_method_visibility, 0); rb_define_method(rb_mKernel, "method", rb_obj_method, 1); rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1); rb_define_method(rb_mKernel, "singleton_method", rb_obj_singleton_method, 1); @@ -2951,6 +2976,7 @@ Init_Proc(void) rb_define_method(rb_cUnboundMethod, "source_location", rb_method_location, 0); rb_define_method(rb_cUnboundMethod, "parameters", rb_method_parameters, 0); rb_define_method(rb_cUnboundMethod, "super_method", method_super_method, 0); + rb_define_method(rb_cUnboundMethod, "visibility", rb_method_visibility, 0); /* Module#*_method */ rb_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1); diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb index 9e20d5c..293e263 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -888,6 +888,19 @@ class TestMethod < Test::Unit::TestCase assert_nil(m, Feature9781) end + def test_visibility_method + v = Visibility.new + assert_equal(:public, v.method(:mv1).visibility) + assert_equal(:private, v.method(:mv2).visibility) + assert_equal(:protected, v.method(:mv3).visibility) + end + + def test_visibility_method_unbound + assert_equal(:public, Visibility.instance_method(:mv1).visibility) + assert_equal(:private, Visibility.instance_method(:mv2).visibility) + assert_equal(:protected, Visibility.instance_method(:mv3).visibility) + end + def rest_parameter(*rest) rest end -- 2.3.2 (Apple Git-55)