2009-03-18 16 views
9

Tôi muốn tạo một lớp có một phương thức gọi tất cả các phương thức khác không nằm trong lớp siêu.Ruby - Lấy mảng các phương thức phi tổ tiên trong lớp

Có cách nào tôi có thể sử dụng obj.methods để chỉ nhận các phương pháp không phải là tổ tiên không? Hoặc là có một cách khác để làm điều đó hoàn toàn.

Cảm ơn bạn

Trả lời

10

Tôi không chắc chắn những gì bạn đang thực sự cố gắng để làm ở đây, cũng không phải phương pháp nào bạn có ý nghĩa bởi "tất cả", nhưng nếu câu hỏi là làm thế nào bạn tìm ra một các phương thức thể hiện của lớp không được kế thừa, sự kết hợp của .instance_methods và .ancestors có thể giúp bạn có được thông tin đó. Ở đây, sử dụng Array làm lớp mẫu:

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

Nếu bạn chỉ muốn loại trừ các phương thức khỏi lớp cha, trái với các phương thức được bao gồm, cũng có .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", "|"] 

Điều đó có hữu ích không?

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

Tôi nghĩ rằng sự kết hợp của cả hai câu trả lời của bạn làm các trick. Thanks guys – stellard

5

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

+0

Điều này là tốt vì nó hoạt động cho các phương thức lớp quá (sử dụng 'phương thức' thay vì' instance_methods'). – mahemoff

0

tôi có thể rộng nhãn hiệu ở đây, nhưng làm thế nào về việc sử dụng 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

Tiêu chuẩn instance_methods phép bạn chỉ định nếu bạn muốn nó để bao gồm các phương pháp lớp cha:

class Foo 
    def bar 
    end 
end 

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

+1 Tôi nghĩ rằng phải có một cái gì đó như thế này. Cảm ơn. – Borodin

Các vấn đề liên quan