简体   繁体   English

在类和它的某个祖先之间定义的实例方法

[英]Instance methods defined between a class and a certain ancestor of it

Suppose class A is a descendant of class B . 假设A类是B类的后代。 What is the best way to get the list (array of symbols, order insignificant) of all instance methods of A defined within B , ie, instance methods of A that are defined on B or any of its descendant class? 获取B定义的A的所有实例方法的列表(符号数组,顺序无关紧要)的最佳方法是什么,即在B或其任何后代类中定义的A实例方法? Example will be as follows. 示例如下。 Where 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

the instance methods of A within various classes would be: 各种类中A的实例方法是:

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))

This is my own solution. 这是我自己的解决方案。

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

Suggested by Marc-André Lafortune: Marc-AndréLafortune建议:

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

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))

I added the special case for Object as Object.instance_methods(false) yields [] , thus the loop traversing upwards would not work well in that case. 我添加了Object as Object.instance_methods(false) yield []的特殊情况,因此在这种情况下向上遍历的循环不会很好。 Updated to define the instance_methods_within class as an instance method of Class . 更新以将instance_methods_within类定义为Class的实例方法。

I would like to present 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM