2016-11-04 2 views
1

Я застрял в двух вещах. Это структура моего файла.Метод, возвращающий список методов экземпляра

class Person 
    #... 
    def self.class_name (object) 
    object.class.name 
    end 
end 

class Worker < Person 
    #... 
end 

class Client < Person 
    #... 
end 

c = Client.new("1", "2", "3", "4") 
Person.class_name(c) 

Я хотел бы создать метод, где в качестве аргумента я могу поставить какой-нибудь предмет, и он обнаружит, какой класс является его и вернуть мне список всех методов экземпляра, которые не требуют каких-либо аргументов. Позже мне нужно как-то использовать все эти методы.

Я нашел это:

testObject.class.name 
# returns name of class as a string 

Class.instance_methods(false) 
# returns list of instance method, which were defined in Class 

Первая проблема, в том, что я не понимаю, почему я не могу сделать что-то вроде

className = testObject.class.name 
className.instance_methods(false) 

Я полагаю, что это потому, что я получил просто класс имя, как жало, а не настоящую ссылку на класс. Я даже создал простой метод class_name, который возвращает правильное имя класса, но мне интересно, как я могу использовать instance_methods(false), как только у меня есть это имя. Также есть ли возможность выбрать только методы, которые не требуют каких-либо аргументов?

ответ

2

Я хотел бы создать метод, где в качестве аргумента я могу поставить какой-то объект и обнаружит, какой класс является его и вернуть мне список всех методов экземпляра

class Person 
    def self.instance_methods(object) 
    object.class.instance_methods(false) 
    end 
end 

Usage :

c = Client.new("1", "2", "3", "4") 
Person.instance_methods(c) 
#=> returns an array of all instance methods defined in Client class 

также есть некоторые опции, чтобы выбрать только те методы, которые не требуют ли каких-либо аргументов?

Да, вы должны проверить method «s arity и выбрать те из них, который имеет нулевой:

class Person 
    def self.instance_methods_with_arity_zero(object) 
    object.class.instance_methods(false).map do |method| 
     object.method(method).arity.zero? 
    end 
    end 
end 

Использование:

c = Client.new("1", "2", "3", "4") 
Person.instance_methods_with_arity_zero(c) 
#=> returns an array of instance methods which take no arguments defined in Client class 

Последний метод можно укоротить, чтобы использовать первые метод определения:

def self.instance_methods_with_arity_zero(object) 
    # we are using the previously defined instance_methods method 
    instance_methods(object).map { |method| object.method(method).arity.zero? } 
end 
+0

Спасибо много! Вы, вероятно, самый быстрый человек, которого я когда-либо видел на любом форуме: D. –

+0

@DanZawadzki добро пожаловать! Это просто совпадение, что я заметил ваш вопрос сразу после его создания: D –

+0

Все работает отлично, но теперь я думаю о том, как «активировать» эти методы. Также вы можете посоветовать мне какой-нибудь хороший ресурс информации о ror? На данный момент я основываюсь на http://ruby-doc.org. Есть ли что-то еще, что я могу использовать? –

1

Вам не нужно, чтобы превратить его в строку:

klass = testObject.class 
methods = klass.instance_methods(false) 

Если вам приходится иметь дело со строковым представлением имени класса, а затем превратить его обратно в класс первый:

klass = "String".constantize 
string_methods = klass.instance_methods(false) 
+0

Спасибо вам большое! Я не понял, что добавление '.name' преобразует его в строку. Я обязательно запомню! –

Смежные вопросы