Project

General

Profile

Feature #11689

Add methods allow us to get visibility from Method and UnboundMethod object.

Added by yui-knk (Kaneko Yuichiro) over 3 years ago. Updated 8 months ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:71490]

Description

Add Method#visibility and UnboundMethod#visibility for getting visibility from Method and UnboundMethod object.
In GitHub https://github.com/ruby/ruby/pull/1098.


Files

History

Updated by hsbt (Hiroshi SHIBATA) over 3 years ago

What's use-case for these methods?

At least, You should describe use-case with feature request.

Updated by yui-knk (Kaneko Yuichiro) over 3 years ago

Sorry.

These methods are useful for inspecting Method object (e.g. debugging or documenting).
Currently if we need information about visibility, we should check owner.public_instance_methods, owner.protected_instance_methods, and owner.private_instance_methods:
see also pry: https://github.com/pry/pry/blob/1f3f7e7ceff27ef516536849fc44fdf010f91c93/lib/pry/method.rb#L343

Updated by MikeVastola (Mike Vastola) 9 months ago

Just wanted to second this FR as something I'd find useful.

Also, it would be nice to have associated predicate methods (i.e. Method#public?, Method#protected? and Method#private?)

Updated by yui-knk (Kaneko Yuichiro) 9 months ago

Thanks for your comment.
Can you show me the use cases where predicate methods are useful?
I think these predicate methods can be implemented by using #visibility method, so these predicate methods should not be needed as core features.

Updated by MikeVastola (Mike Vastola) 9 months ago

Oh, sorry. I missed where you were looking for an example before. Here's a good one from the popular activesupport gem: here.

As for the predicate methods, yes, they can be derrived from core methods and they -- like most core predicate methods, -- would be for convenience, but I disagree that that should be the determining factor. The same could be said for #nil?, #is_a?, #respond_to? and #*_defined? -- the functionality of which could be accomplished by checking the results of other core methods.

Updated by shevegen (Robert A. Heiler) 9 months ago

(I think it may be easier to file a separate issue for the predicate methods,
such as Method#public?, Method#protected? or Method#private?).

Kaneko Yuichiro added the issue to the next upcoming developer meeting. Let's
see to the upcoming discussion of matz and the core developers and matz.

Updated by matz (Yukihiro Matsumoto) 8 months ago

The proposal sounds nice, but I am not fully satisfied with the term visibility. So how about adding public?, private? and protected? methods instead?

Matz.

Updated by MikeVastola (Mike Vastola) 8 months ago

I mean, as seen in yui-knk's example with pry, I think it's helpful to be able to essentially do send("#{method.visibility}_instance_methods"). I'm not picky on the name though if there is something better than visibility.

But I think it makes sense to address any/all methods that are introduced in this issue.

Updated by mame (Yusuke Endoh) 8 months ago

I don't think that send("#{method.visibility}_instance_methods") would be a frequent, strongly-recommended idiom. You can do it more explicitly as follows.

def visibility(method)
  case
  when method.public?    then "public_instance_methods"
  when method.protected? then "protected_instance_methods"
  when method.private?   then "private_instance_methods"
  else raise "unknown method type"
  end
end

This code would require work if a new visibility is introduced. But, there is no plan to add a new visibility in foreseeable future. Also, if something is actually introduced, there is no guarantee that the idiom would work as is.

Updated by Eregon (Benoit Daloze) 8 months ago

I think visibility is the perfect, accurate and unambiguous term for this (e.g., it's even used in the documentation of #private).
Returning the corresponding Symbol also seems very intuitive.

So take my vote as +1 for Method#visibility and -1 for 3 methods which seem very inconvenient to use.
Basically, it's 1 method versus 3 and it's strictly more expressive/powerful (the result can be displayed easily for introspection, and also compared to a known visibility).

Updated by mame (Yusuke Endoh) 8 months ago

FYI: The reason why matz does not like the term "visibility", is because the method attribute is not a visibility. In fact, all methods are visible in Ruby. Instead, the method attribute restricts how and where it can be called. We briefly discussed another name candidate at the meeting, but we couldn't find a good name of the concept. Then matz chose the three methods (public?, etc.) because we can avoid deciding the name.

Updated by Eregon (Benoit Daloze) 8 months ago

mame (Yusuke Endoh) wrote:

FYI: The reason why matz does not like the term "visibility", is because the method attribute is not a visibility. In fact, all methods are visible in Ruby. Instead, the method attribute restricts how and where it can be called. We briefly discussed another name candidate at the meeting, but we couldn't find a good name of the concept. Then matz chose the three methods (public?, etc.) because we can avoid deciding the name.

Thanks for the information :)

Right, the visibility does not affect how to call the method reflectively (which is done with Method#call), but reflects the visibility in the context of normal calls.
To be honest, I expect very few people to be confused by this.
I think it's clear it means the definition time visibility.
Metaprogramming methods in general ignore visibility (or enforce public with #public_send), so a visibility for how to call the Method object wouldn't make sense anyway.

Instead, the method attribute restricts how and where it can be called.
We briefly discussed another name candidate at the meeting, but we couldn't find a good name of the concept.

Visibility is the standard term to talk about public/protected/private and restrictions of how and where a method can be called, in all languages I know.
I think no other term makes more sense than visibility, and it is a well-known concept in programming languages.
Maybe in other natural languages this is confusing? I think in English it's as clear as it can be for an established concept.

In fact, all methods are visible in Ruby.

I'm not sure what you mean here. But one could say "method m in class A is not visible to instances of class B" and that would apply to Ruby if m is private.

Updated by duerst (Martin Dürst) 8 months ago

I agree that #visibility is the best solution. When somebody mentioned this at the recent Ruby committers' meeting, I immediately thought "that's it". Benoit provides some more background.

There are arguments that this may be misunderstood, but so might the original keywords public, protected, and private, and many other Ruby keywords and names. Ruby users already have to learn that private doesn't really mean private, that in Ruby, there's always some metaprogamming workaround. Once they now it, they will apply this to #visibility without much problems.

Also available in: Atom PDF