10 votes

Ruby - Obtenir un tableau de méthodes non ancestrales dans une classe

Je veux créer une classe qui a une méthode qui appelle toutes les autres méthodes qui ne sont pas dans la super classe.

Existe-t-il un moyen d'utiliser obj.methods pour obtenir uniquement les méthodes non ancestrales ? Ou existe-t-il un autre moyen de le faire entièrement.

Merci.

15voto

Semyon Perepelitsa Points 7592

La norme instance_methods vous permet de spécifier si vous voulez qu'il inclue les méthodes de la superclasse :

class Foo
  def bar
  end
end

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

10voto

glenn mcdonald Points 8933

Je ne suis pas sûr de ce que vous essayez de faire ici, ni de quelles méthodes vous entendez par "toutes", mais si la question est de savoir comment déterminer quelles méthodes d'instance d'une classe ne sont pas héritées, la combinaison de .instance_methods et .ancestors peut vous donner cette information. Ici, en utilisant Array comme classe d'exemple :

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", "|"]

Si vous voulez littéralement exclure uniquement les méthodes de la superclasse, par opposition à celles qui sont incluses, il y a aussi .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", "|"]

Est-ce que ça aide ?

5voto

guyinsb Points 49

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

2voto

Marcin Urbanski Points 925
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

0voto

Borodin Points 52478

Je suis peut-être à côté de la plaque ici, mais pourquoi ne pas utiliser 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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X