Skip to content

Commit 2727815

Browse files
committed
Add {Method,UnboundMethod}#{public?,private?,protected?}
These methods allow for checking whether the method has that visibility. Implements [Feature ruby#11689]
1 parent 74159f7 commit 2727815

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

NEWS.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Note that each entry is kept to a minimum, see links for details.
77

88
## Language changes
99

10-
* The block arguments can be now be anonymous, if the block will
10+
* The block argument can be now be anonymous, if the block will
1111
only be passed to another method. [[Feature #11256]]
1212

1313
```ruby
@@ -190,6 +190,11 @@ Outstanding ones only.
190190
191191
* MatchData#match_length is added [[Feature #18172]]
192192
193+
* Method/UnboundMethod
194+
195+
* #public?, #private?, #protected have been added to both
196+
Method and UnboundMethod. [[Feature #11689]]
197+
193198
* Module
194199
195200
* 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.
459464
[Bug #4443]: https://bugs.ruby-lang.org/issues/4443
460465
[Feature #6210]: https://bugs.ruby-lang.org/issues/6210
461466
[Feature #11256]: https://bugs.ruby-lang.org/issues/11256
467+
[Feature #11689]: https://bugs.ruby-lang.org/issues/11689
462468
[Feature #12194]: https://bugs.ruby-lang.org/issues/12194
463469
[Feature #12495]: https://bugs.ruby-lang.org/issues/12495
464470
[Feature #12913]: https://bugs.ruby-lang.org/issues/12913

proc.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3227,6 +3227,51 @@ method_super_method(VALUE method)
32273227
return mnew_internal(me, me->owner, iclass, data->recv, mid, rb_obj_class(method), FALSE, FALSE);
32283228
}
32293229

3230+
/*
3231+
* call-seq:
3232+
* meth.public? -> true or false
3233+
*
3234+
* Returns whether the method is public.
3235+
*/
3236+
3237+
static VALUE
3238+
method_public_p(VALUE method)
3239+
{
3240+
const struct METHOD *data;
3241+
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
3242+
return RBOOL(METHOD_ENTRY_VISI(data->me) == METHOD_VISI_PUBLIC);
3243+
}
3244+
3245+
/*
3246+
* call-seq:
3247+
* meth.protected? -> true or false
3248+
*
3249+
* Returns whether the method is protected.
3250+
*/
3251+
3252+
static VALUE
3253+
method_protected_p(VALUE method)
3254+
{
3255+
const struct METHOD *data;
3256+
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
3257+
return RBOOL(METHOD_ENTRY_VISI(data->me) == METHOD_VISI_PROTECTED);
3258+
}
3259+
3260+
/*
3261+
* call-seq:
3262+
* meth.private? -> true or false
3263+
*
3264+
* Returns whether the method is private.
3265+
*/
3266+
3267+
static VALUE
3268+
method_private_p(VALUE method)
3269+
{
3270+
const struct METHOD *data;
3271+
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
3272+
return RBOOL(METHOD_ENTRY_VISI(data->me) == METHOD_VISI_PRIVATE);
3273+
}
3274+
32303275
/*
32313276
* call-seq:
32323277
* local_jump_error.exit_value -> obj
@@ -4163,6 +4208,9 @@ Init_Proc(void)
41634208
rb_define_method(rb_cMethod, "source_location", rb_method_location, 0);
41644209
rb_define_method(rb_cMethod, "parameters", rb_method_parameters, 0);
41654210
rb_define_method(rb_cMethod, "super_method", method_super_method, 0);
4211+
rb_define_method(rb_cMethod, "public?", method_public_p, 0);
4212+
rb_define_method(rb_cMethod, "protected?", method_protected_p, 0);
4213+
rb_define_method(rb_cMethod, "private?", method_private_p, 0);
41664214
rb_define_method(rb_mKernel, "method", rb_obj_method, 1);
41674215
rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1);
41684216
rb_define_method(rb_mKernel, "singleton_method", rb_obj_singleton_method, 1);
@@ -4186,6 +4234,9 @@ Init_Proc(void)
41864234
rb_define_method(rb_cUnboundMethod, "source_location", rb_method_location, 0);
41874235
rb_define_method(rb_cUnboundMethod, "parameters", rb_method_parameters, 0);
41884236
rb_define_method(rb_cUnboundMethod, "super_method", method_super_method, 0);
4237+
rb_define_method(rb_cUnboundMethod, "public?", method_public_p, 0);
4238+
rb_define_method(rb_cUnboundMethod, "protected?", method_protected_p, 0);
4239+
rb_define_method(rb_cUnboundMethod, "private?", method_private_p, 0);
41894240

41904241
/* Module#*_method */
41914242
rb_define_method(rb_cModule, "instance_method", rb_mod_instance_method, 1);

test/ruby/test_method.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,25 @@ def foo
11811181
assert_nil(super_method)
11821182
end
11831183

1184+
def test_method_visibility_predicates
1185+
v = Visibility.new
1186+
assert_equal(true, v.method(:mv1).public?)
1187+
assert_equal(true, v.method(:mv2).private?)
1188+
assert_equal(true, v.method(:mv3).protected?)
1189+
assert_equal(false, v.method(:mv2).public?)
1190+
assert_equal(false, v.method(:mv3).private?)
1191+
assert_equal(false, v.method(:mv1).protected?)
1192+
end
1193+
1194+
def test_unbound_method_visibility_predicates
1195+
assert_equal(true, Visibility.instance_method(:mv1).public?)
1196+
assert_equal(true, Visibility.instance_method(:mv2).private?)
1197+
assert_equal(true, Visibility.instance_method(:mv3).protected?)
1198+
assert_equal(false, Visibility.instance_method(:mv2).public?)
1199+
assert_equal(false, Visibility.instance_method(:mv3).private?)
1200+
assert_equal(false, Visibility.instance_method(:mv1).protected?)
1201+
end
1202+
11841203
def rest_parameter(*rest)
11851204
rest
11861205
end

0 commit comments

Comments
 (0)