ruby-changes:70138
From: Jeremy <ko1@a...>
Date: Fri, 10 Dec 2021 06:00:10 +0900 (JST)
Subject: [ruby-changes:70138] 2727815068 (master): Add {Method, UnboundMethod}#{public?, private?, protected?}
https://git.ruby-lang.org/ruby.git/commit/?id=2727815068 From 27278150685e738f84105d09843d3ba371146c7a Mon Sep 17 00:00:00 2001 From: Jeremy Evans <code@j...> Date: Wed, 27 Oct 2021 15:36:00 -0700 Subject: Add {Method,UnboundMethod}#{public?,private?,protected?} These methods allow for checking whether the method has that visibility. Implements [Feature #11689] --- NEWS.md | 8 +++++++- proc.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ test/ruby/test_method.rb | 19 ++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index e1918b445e1..d747db3f56e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -7,7 +7,7 @@ Note that each entry is kept to a minimum, see links for details. https://github.com/ruby/ruby/blob/trunk/NEWS.md#L7 ## Language changes -* The block arguments can be now be anonymous, if the block will +* The block argument can be now be anonymous, if the block will only be passed to another method. [[Feature #11256]] ```ruby @@ -190,6 +190,11 @@ Outstanding ones only. https://github.com/ruby/ruby/blob/trunk/NEWS.md#L190 * MatchData#match_length is added [[Feature #18172]] +* Method/UnboundMethod + + * #public?, #private?, #protected have been added to both + Method and UnboundMethod. [[Feature #11689]] + * Module * Module#prepend now modifies the ancestor chain if the receiver @@ -459,6 +464,7 @@ See [the repository](https://github.com/ruby/error_highlight) in detail. https://github.com/ruby/ruby/blob/trunk/NEWS.md#L464 [Bug #4443]: https://bugs.ruby-lang.org/issues/4443 [Feature #6210]: https://bugs.ruby-lang.org/issues/6210 [Feature #11256]: https://bugs.ruby-lang.org/issues/11256 +[Feature #11689]: https://bugs.ruby-lang.org/issues/11689 [Feature #12194]: https://bugs.ruby-lang.org/issues/12194 [Feature #12495]: https://bugs.ruby-lang.org/issues/12495 [Feature #12913]: https://bugs.ruby-lang.org/issues/12913 diff --git a/proc.c b/proc.c index 94b269d6946..90ecf1e59bb 100644 --- a/proc.c +++ b/proc.c @@ -3227,6 +3227,51 @@ method_super_method(VALUE method) https://github.com/ruby/ruby/blob/trunk/proc.c#L3227 return mnew_internal(me, me->owner, iclass, data->recv, mid, rb_obj_class(method), FALSE, FALSE); } +/* + * call-seq: + * meth.public? -> true or false + * + * Returns whether the method is public. + */ + +static VALUE +method_public_p(VALUE method) +{ + const struct METHOD *data; + TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); + return RBOOL(METHOD_ENTRY_VISI(data->me) == METHOD_VISI_PUBLIC); +} + +/* + * call-seq: + * meth.protected? -> true or false + * + * Returns whether the method is protected. + */ + +static VALUE +method_protected_p(VALUE method) +{ + const struct METHOD *data; + TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); + return RBOOL(METHOD_ENTRY_VISI(data->me) == METHOD_VISI_PROTECTED); +} + +/* + * call-seq: + * meth.private? -> true or false + * + * Returns whether the method is private. + */ + +static VALUE +method_private_p(VALUE method) +{ + const struct METHOD *data; + TypedData_Get_Struct(method, struct METHOD, &method_data_type, data); + return RBOOL(METHOD_ENTRY_VISI(data->me) == METHOD_VISI_PRIVATE); +} + /* * call-seq: * local_jump_error.exit_value -> obj @@ -4163,6 +4208,9 @@ Init_Proc(void) https://github.com/ruby/ruby/blob/trunk/proc.c#L4208 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, "public?", method_public_p, 0); + rb_define_method(rb_cMethod, "protected?", method_protected_p, 0); + rb_define_method(rb_cMethod, "private?", method_private_p, 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); @@ -4186,6 +4234,9 @@ Init_Proc(void) https://github.com/ruby/ruby/blob/trunk/proc.c#L4234 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, "public?", method_public_p, 0); + rb_define_method(rb_cUnboundMethod, "protected?", method_protected_p, 0); + rb_define_method(rb_cUnboundMethod, "private?", method_private_p, 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 daf0ec73ca1..da68787933e 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -1181,6 +1181,25 @@ class TestMethod < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_method.rb#L1181 assert_nil(super_method) end + def test_method_visibility_predicates + v = Visibility.new + assert_equal(true, v.method(:mv1).public?) + assert_equal(true, v.method(:mv2).private?) + assert_equal(true, v.method(:mv3).protected?) + assert_equal(false, v.method(:mv2).public?) + assert_equal(false, v.method(:mv3).private?) + assert_equal(false, v.method(:mv1).protected?) + end + + def test_unbound_method_visibility_predicates + assert_equal(true, Visibility.instance_method(:mv1).public?) + assert_equal(true, Visibility.instance_method(:mv2).private?) + assert_equal(true, Visibility.instance_method(:mv3).protected?) + assert_equal(false, Visibility.instance_method(:mv2).public?) + assert_equal(false, Visibility.instance_method(:mv3).private?) + assert_equal(false, Visibility.instance_method(:mv1).protected?) + end + def rest_parameter(*rest) rest end -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/