Instance methods defined between a class and its predecessor

Suppose a class Ais a descendant of a class B. What is the best way to get a list (array of characters, order of non-essentials) of all instance methods Adefined in B, i.e. Instance methods Athat are defined in Bor any of its descendant classes? An example will be as follows. If the class hierarchy is as follows:

class C; def c; end end
class B < C; def b; end end
class D < B; def d; end end
class A < D; def a; end end

instance methods Ain different classes:

A.instance_methods_within(Kernel) # =>  (Same as A.instance_methods)
A.instance_methods_within(C) # => [:a, :d, :b, :c]
A.instance_methods_within(B) # => [:a, :d, :b]
A.instance_methods_within(D) # => [:a, :d]
A.instance_methods_within(A) # => [:a]  (Same as A.instance_methods(false))
+4
source share
3 answers

I believe you are looking for this:

class Class
  def instance_methods_within(klass)
    return self.instance_methods if klass == Object
    methods = []
    this = self
    while this != nil
      methods << this.instance_methods(false)
      break if this == klass
      this = this.superclass
    end

    return methods.flatten
  end
end

class C; def c; end end
class B < C; def b; end end
class D < B; def d; end end
class A < D; def a; end end

A.instance_methods_within(Object) # =>  (Same as A.instance_methods)
A.instance_methods_within(C) # => [:a, :d, :b, :c]
A.instance_methods_within(B) # => [:a, :d, :b]
A.instance_methods_within(D) # => [:a, :d]
A.instance_methods_within(A) # => [:a]  (Same as A.instance_methods(false))

Object, Object.instance_methods(false) [], , , . , instance_methods_within Class.

+2

.

class Class
  def instance_methods_within klass
    ancestors
    .select{|k| k <= klass}
    .inject([]){|a, k| a.concat(k.instance_methods(false))}
    .uniq
  end
end

- :

class Class
  def instance_methods_within klass
    ancestors
    .select{|k| k <= klass}
    .flat_map{|k| k.instance_methods(false)}
    .uniq
  end
end
+4

I would like to introduce this: -

    class Class
      def instance_methods_within(klass = nil)
        imethods = instance_methods
        own_imethods = instance_methods(false)
        return imethods if [Object, Kernel, nil].include?(klass) || [BasicObject, nil].include?(klass.superclass)
        sc_imethods = klass.superclass.instance_methods
        own_imethods | (imethods - sc_imethods)
      end
    end
-1
source

Source: https://habr.com/ru/post/1532099/


All Articles