Ruby - 在类中获取非祖先方法的数组

Posted

技术标签:

【中文标题】Ruby - 在类中获取非祖先方法的数组【英文标题】:Ruby - Getting Array of non-ancestral methods in class 【发布时间】:2010-10-14 04:10:44 【问题描述】:

我想创建一个类,它有一个方法可以调用不在超类中的所有其他方法。

有没有办法可以使用 obj.methods 来仅获取非祖先方法?或者有其他方法可以完全做到这一点。

谢谢

【问题讨论】:

【参考方案1】:

标准instance_methods 允许您指定是否要包含超类方法:

class Foo
  def bar
  end
end

Foo.instance_methods(false) # => [:bar]

【讨论】:

【参考方案2】:

我在这里可能不太清楚,但是使用owner 怎么样?

methods = obj.methods.map  |sym| obj.method(sym) .
own_methods = methods.find_all  |mth| mth.owner == obj.class 

own_methods.each do |mth|
  mth.to_proc.call
end

【讨论】:

【参考方案3】:

obj1.class.instance_methods - obj1.class.superclass.instance_methods

【讨论】:

这很好,因为它也适用于类方法(使用methods 而不是instance_methods)。【参考方案4】:

我不确定您在这里真正想要做什么,也不确定您所说的“全部”是哪些方法,但如果问题是您如何确定哪些类的实例方法没有被继承,那么组合.instance_methods 和 .ancestors 可以为您提供该信息。这里以 Array 类为例:

Array.instance_methods.sort                                                                         
=> ["&", "*", "+", "-", "<<", "<=>", "==", "===", "=~", "[]", "[]=", "__id__", "__send__", "all?", "any?", "assoc", "at", "class", "clear", "clone", "collect", "collect!", "compact", "compact!", "concat", "delete", "delete_at", "delete_if", "detect", "display", "dup", "each", "each_index", "each_with_index", "empty?", "entries", "eql?", "equal?", "extend", "fetch", "fill", "find", "find_all", "first", "flatten", "flatten!", "freeze", "frozen?", "grep", "hash", "id", "include?", "index", "indexes", "indices", "inject", "insert", "inspect", "instance_eval", "instance_of?", "instance_variable_get", "instance_variable_set", "instance_variables", "is_a?", "join", "kind_of?", "last", "length", "map", "map!", "max", "member?", "method", "methods", "min", "nil?", "nitems", "object_id", "pack", "partition", "pop", "private_methods", "protected_methods", "public_methods", "push", "rassoc", "reject", "reject!", "replace", "respond_to?", "reverse", "reverse!", "reverse_each", "rindex", "select", "send", "shift", "singleton_methods", "size", "slice", "slice!", "sort", "sort!", "sort_by", "taint", "tainted?", "to_a", "to_ary", "to_s", "transpose", "type", "uniq", "uniq!", "unshift", "untaint", "values_at", "zip", "|"]

Array.ancestors
=> [Array, Enumerable, Object, Kernel]

Array.instance_methods.sort - Array.ancestors.map |a| a == Array ? [] : a.instance_methods.flatten
=> ["&", "*", "+", "-", "<<", "<=>", "[]", "[]=", "assoc", "at", "clear", "collect!", "compact", "compact!", "concat", "delete", "delete_at", "delete_if", "each", "each_index", "empty?", "fetch", "fill", "first", "flatten", "flatten!", "index", "indexes", "indices", "insert", "join", "last", "length", "map!", "nitems", "pack", "pop", "push", "rassoc", "reject!", "replace", "reverse", "reverse!", "reverse_each", "rindex", "shift", "size", "slice", "slice!", "sort!", "to_ary", "transpose", "uniq", "uniq!", "unshift", "values_at", "|"]

如果您只想从超类中排除方法,而不是包含的方法,那么还有 .superclass。

Array.superclass
=> Object

Array.instance_methods.sort - Array.superclass.instance_methods
=> ["&", "*", "+", "-", "<<", "<=>", "[]", "[]=", "all?", "any?", "assoc", "at", "clear", "collect", "collect!", "compact", "compact!", "concat", "delete", "delete_at", "delete_if", "detect", "each", "each_index", "each_with_index", "empty?", "entries", "fetch", "fill", "find", "find_all", "first", "flatten", "flatten!", "grep", "include?", "index", "indexes", "indices", "inject", "insert", "join", "last", "length", "map", "map!", "max", "member?", "min", "nitems", "pack", "partition", "pop", "push", "rassoc", "reject", "reject!", "replace", "reverse", "reverse!", "reverse_each", "rindex", "select", "shift", "size", "slice", "slice!", "sort", "sort!", "sort_by", "to_ary", "transpose", "uniq", "uniq!", "unshift", "values_at", "zip", "|"]

这有帮助吗?

【讨论】:

【参考方案5】:
class MassiveCall
  def method1
    puts "calling method1"
  end

  def method2
    puts "calling method2"
  end

  def method3
    puts "calling method3"
  end

  def one_method_to_rule_them_all
    # skip one_method_to_rule_them_all to avoid infinite recursion:
    methods = self.class.instance_methods(false) - ["one_method_to_rule_them_all"]
    methods.each do |method_name|
      self.send(method_name)
    end
  end
end

master = MassiveCall.new
master.one_method_to_rule_them_all

【讨论】:

我认为您的两个答案的组合可以解决问题。谢谢大家

以上是关于Ruby - 在类中获取非祖先方法的数组的主要内容,如果未能解决你的问题,请参考以下文章

获取存储在类中的异常对象时,Junit 测试失败,而不是抛出

c ++:使用模板在类中定义可变长度数组

在类中获取指向自身的指针

在类之间存储和传递数据的正确方法

使用 WebDriver 和 Selenium 在类中获取跨度

在类中定义数组的方法和字段