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

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/

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