2009-03-18 8 views
9

Chcę utworzyć klasę, która ma jedną metodę, która wywołuje wszystkie inne metody, które nie należą do super klasy.Ruby - Uzyskanie tablicy metod nie-przodkowych w klasie

Czy istnieje sposób, w jaki można użyć obj.methods, aby uzyskać tylko metody nie-przodków? Czy istnieje inny sposób, aby to zrobić w całości.

Dziękuję

Odpowiedz

10

Nie jestem pewien, co tak naprawdę staramy się robić tu, ani metody, które znaczy „wszystko”, ale jeśli chodzi o to, w jaki sposób dowiedzieć się, która z pewnej Metody instancji klasy nie są dziedziczone, dlatego połączenie metod .instance_methods i .ancestors umożliwia uzyskanie tych informacji. Tutaj, za pomocą tablicy jako klasy np:

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

Jeśli dosłownie chcą tylko, aby wykluczyć metody z nadklasy, w przeciwieństwie do nich zawartych, jest również .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", "|"] 

Czy to pomaga?

2
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 
+0

Myślę, że połączenie obu odpowiedziach załatwia sprawę. Dzięki chłopaki – stellard

5

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

+0

To jest dobre, ponieważ działa również dla metod klasowych (używając 'method' zamiast' instance_methods'). – mahemoff

0

mogą być chybione tutaj, ale jak o użyciu 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 
13

Standardowa instance_methods pozwala określić, czy chcesz go do obejmują metody nadklasy:

class Foo 
    def bar 
    end 
end 

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

+1 Myślałem, że musi być coś takiego. Dzięki. – Borodin

Powiązane problemy