Project

General

Profile

Actions

Feature #2170

closed

Visibility Predicates for Method Objects

Added by runpaint (Run Paint Run Run) over 14 years ago. Updated almost 13 years ago.

Status:
Rejected
Target version:
-
[ruby-core:25908]

Description

=begin
A Method object doesn't expose the wrapped method's visibility. If you have the method name as a Symbol, however, Module#*_method_defined? can be used. This seems wrong. A naïve patch is attached to add visibility predicates to Method and UnboundMethod.
=end


Files

Actions #1

Updated by marcandre (Marc-Andre Lafortune) over 14 years ago

  • Assignee set to matz (Yukihiro Matsumoto)

=begin
I'm trying to see how that could be useful, to understand your goal.

Once you have a Method (or an Unbound one), the visibility is no longer relevant. What I mean is that the visibility affects only the calls like my_obj.some_method, but if one obtains that method, there is no problem calling it even if it was private (similar to using send which ignores accessibility). Since this accessibility has no consequence once you have your Method object, I wonder why it could be useful to call method.private?

Moreover I see problems with defining it. The original method could have changed of accessibility or no longer exist. method#private? returns the accessibility at the moment the Method was created, which seems even less useful.

Similarly, results with aliases can be counterintuive.

Code example:

class X
def f; foo; end
alias_method :g, :f
private :f
end
x = X.new
f = x.method(:f)
g = x.method(:g)
class X
private :g
end
g2 = x.method(:g)
f == g # ==> true
g == g2 # ==> true
f.private? == g.private? # ==> false
g.private? == g2.private? # ==> false

=end

Actions #2

Updated by runpaint (Run Paint Run Run) over 14 years ago

=begin

I'm trying to see how that could be useful, to understand your goal.

A method's visibility is one of its attributes. The Method class objectifies methods, so it is expected that it provides access to the wrapped method's attributes. This abstraction is broken when you must retrieve the Method's name, then pass it to another class to determine such an attribute.

If you're using Method objects to obtain the source code of a method it is probable that you're producing documentation or performing static analysis, both of which would likely at least benefit from visibility metadata. If you're using Method objects to copy methods to other classes or objects, such as with define_method, it is probable that you want to reinstate the method with its original visibility. Indeed, most examples of using Method objects that come to mind would be bolstered by this data.

Moreover I see problems with defining it. The original method could have changed of
accessibility or no longer exist. method#private? returns the accessibility at the moment
the Method was created, which seems even less useful.

It could have changed its arity or source, too, depending on how you're defining "original method". A Method object represents the method at the point it was objectified.

Similarly, results with aliases can be counterintuive.

It would be surprising if a "naïve", proof-of-concept patch on a codebase with which I'm unfamiliar was perfect. I don't see how aliases are a conceptual problem.

Anyway, it was but a suggestion; if it lacks general utility then by all means close the ticket.
=end

Actions #3

Updated by matz (Yukihiro Matsumoto) over 14 years ago

=begin
Hi,

In message "Re: [ruby-core:25908] [Feature #2170] Visibility Predicates for Method Objects"
on Sat, 3 Oct 2009 04:50:54 +0900, Run Paint Run Run writes:

|A Method object doesn't expose the wrapped method's visibility. If you have the method name as a Symbol, however, Module#*_method_defined? can be used. This seems wrong. A naïve patch is attached to add visibility predicates to Method and UnboundMethod.

A method object represents the body (definition) of a method, where
visibility is a property of binding (name -> method body) in the
class. So, in theory, I think a method object should not have the
visibility information. Am I wrong?

						matz.

=end

Actions #4

Updated by marcandre (Marc-Andre Lafortune) over 14 years ago

=begin
I think Matz summarized clearly what I was trying to say.

Run Paint: I'm sorry if I implied there was a problem with your patch. This is not the case. I'm discussing the idea, not the implementation which appears to be great, actually.

You talk about #arity and #source_location. That's a good comparison, but it also shows how they differ from #private?. Take any two methods f and f where f == g. Then f.arity == g.arity and f.source_location == g.source_location. My examples were meant to show that f.private? isn't always == g.private?, in an attempt to show that it's not a property of the method itself.

=end

Actions #5

Updated by runpaint (Run Paint Run Run) over 14 years ago

=begin
Feel free to close.
=end

Actions #6

Updated by marcandre (Marc-Andre Lafortune) over 14 years ago

  • Status changed from Open to Closed

=begin

=end

Actions #7

Updated by yugui (Yuki Sonoda) over 14 years ago

  • Status changed from Closed to Rejected

=begin

=end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0