Issue #7836 has been updated by marcandre (Marc-Andre Lafortune).


banister (john mair) wrote:
> @ marcandre. Another possible approach is to provide `UnboundMethod#super`.

Not a bad idea, for Method also, although I'm not sure if it would be useful to many. You might want to make another feature request for this (and provide a decent justification!).

> While we're at it, other useful methods for `Method/UnboundMethod` could be private?, public?, aliases, singleton? :) but that could be asking for too much ;)

These might be more problematic:

* privacy
It is not really an attribute of the method itself. It's an attribute of the class, i.e. does the class provide public access to a method.

    class F
      def priv; end
      alias_method :pub, :priv
      private :priv
    end
    F.new.pub # => nil
    F.new.priv # => NoMethodError: private method `priv' called
    F.instance_method(:pub) == F.instance_method(:priv) # => true

So I think that Module#private_method_defined? and Module#private_instance_methods are the ones you want to use.

* aliases
Not sure who would use this, but you can already easily do this by comparing the unbound methods:

    String.instance_methods.group_by{|x| String.instance_method(x)}.map(&:last).reject(&:one?)
     # => [[:==, :===], [:[], :slice], [:length, :size], [:succ, :next], [:succ!, :next!], [:to_s, :to_str], [:concat, :<<],
               [:intern, :to_sym], [:kind_of?, :is_a?], [:send, :__send__], [:object_id, :__id__], [:to_enum, :enum_for]]

Or if you prefer:

    class UnboundMethod
      def aliases
        owner.instance_methods.select{|m| owner.instance_method(m) == self}
      end
    end

     String.instance_method(:size).aliases # => [:length, :size]

* singleton?

This is a property of the owner, no? Module#singleton_class? already accepted: https://bugs.ruby-lang.org/issues/7609

So if you really want, you will be able to roll your own easily:

    class UnboundMethod
      def singleton?
        owner.is_a?(Class) && owner.singleton_class?
      end
    end


----------------------------------------
Feature #7836: Need a way to get Method and UnboundMethod objects to methods overridden by prepended modules
https://bugs.ruby-lang.org/issues/7836#change-37311

Author: banister (john mair)
Status: Open
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: 
Target version: 


=begin
See the following code:

  module P
    def hello
      puts "from P"
      super
    end
  end

  class A
    def hello
      puts 'from A'
    end

    prepend P
  end

  A.instance_method(:hello).source_location == P.instance_method(:hello).source_location  #=> true

== Discussion

Since (({A.instance_method(:hello)})) effectively returns (({P.instance_method(:hello)})) it is impossible to get an (({UnboundMethod})) object to the original (({A#hello})) method.

Tools like ((<[Pry]|URL:http://pryrepl.org>)) need to access (({UnboundMethod})) objects to every active method in the system for debugging purposes.

== Possible solution

Simply allow (({instance_method()})) to take a second boolean parameter, indicating whether methods injected by prepended modules are to be included, it would default to true:

example:

  A.instance_method(:hello) #=> same as P#hello
  A.instance_method(:hello, false) #=> return strictly A#hello

=end



-- 
http://bugs.ruby-lang.org/