簡體   English   中英

在類和它的某個祖先之間定義的實例方法

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

假設A類是B類的后代。 獲取B定義的A的所有實例方法的列表(符號數組,順序無關緊要)的最佳方法是什么,即在B或其任何后代類中定義的A實例方法? 示例如下。 類層次結構如下:

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的實例方法是:

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

這是我自己的解決方案。

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

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

我相信你在尋找這個:

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 as Object.instance_methods(false) yield []的特殊情況,因此在這種情況下向上遍歷的循環不會很好。 更新以將instance_methods_within類定義為Class的實例方法。

我想提出這個問題: -

    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