Отримайте список методів екземплярів класу


Відповіді:


115

Ви насправді хочете TestClass.instance_methods, якщо тільки вас не цікавить, що TestClassсаме ви можете зробити.

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

TestClass.methods.grep(/method1/) # => []
TestClass.instance_methods.grep(/method1/) # => ["method1"]
TestClass.methods.grep(/new/) # => ["new"]

Або ви можете зателефонувати methods(не instance_methods) на об’єкт:

test_object = TestClass.new
test_object.methods.grep(/method1/) # => ["method1"]

3
Хе, ти побив мене на 47 секунд. +1
Фрогц,

2
Коли я намагаюся print TestClass.new.instance_methods, я отримую цю помилкуmy_class.rb:10:in <main>: undefined method instance_methods for #<TestClass:0x96b9d20> (NoMethodError)
Володимир Цуканов,

Вам потрібно лише зробити TestClass.new.methods. Можливо, "це" було неоднозначним у моїй відповіді.
Ендрю Грімм,

Зауважте, що під Ruby 1.9+ імена методів є символами, а не рядками.
Phrogz

1
@Phrogz: Так, але вам дозволяється використовувати регулярні вирази на них. Ти навіть не викликаєш Ктулху! :) Хоча ви отримаєте [:method1]замість цього.
Ендрю Грімм,

113
TestClass.methods(false) 

отримати лише методи, що належать лише до цього класу.

TestClass.instance_methods(false) поверне методи з вашого наведеного прикладу (оскільки вони є примірниками методів TestClass).


2
Це чудовий спосіб перевірити, чи має клас поліморфізовані методи з базового класу псевдо-інтерфейсу / абстрактності, не намагаючись викликати методи безпосередньо.
Даніель Доезема

2
Прийнята відповідь чудова, але ця, ймовірно, заради чого більше людей сюди приїде!
Аарон

Це однозначно має бути прийнятою відповіддю. ДЯКУЮ!
Вініцій

38
TestClass.instance_methods

або без усіх успадкованих методів

TestClass.instance_methods - Object.methods

(Було 'TestClass.methods - Object.methods')


25
або без успадкованих методів: TestClass.methods(false).
sawa

2
@sawa TestClass.methods(false)повертається порожнім
Володимир Цуканов

1
Ця відповідь неправильна; результати не включатимуть method1, method2або method3, оскільки це методи екземплярів класу, а не методи самого TestClassоб'єкта.
Phrogz

1
@Phrogz: На жаль ... так, "TestClass.instan_methods - Object.methods" або "TestClass.new.methods - Object.methods" ..., які навчать мене не запускати консоль. Краще для мене видалити цю відповідь або відредагувати її?
Pavling

1
@Pavling Однозначно відредагуйте свою відповідь правильною. (Швидко, перш ніж ОП передає кредит комусь іншому! :)
Фрогц,

6

Ви можете отримати більш детальний список (наприклад, структурований за визначенням класу) з такими дорогоцінними каменями, як налагодження або looksee .


6
$ irb --simple-prompt

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

tc_list = TestClass.instance_methods(false)
#[:method1, :method2, :method3]
puts tc_list
#method1
#method2
#method3

2
Це занадто схоже на інші відповіді і не додає додаткової інформації та ясності.
Зміст

3
Ви не змогли згадати, що це теж дуже пізно. : D
Дуглас Г. Аллен

2

Відповідно до методів Ruby Doc instance_methods

Повертає масив, що містить назви загальнодоступних та захищених методів екземпляра у приймачі. Для модуля це загальнодоступні та захищені методи; для класу вони є методами екземпляра (не однотонними). Якщо необов'язковий параметр false, методи будь-яких предків не включаються. Я беру приклад з офіційної документації.

module A
  def method1()  
    puts "method1 say hi"
  end
end
class B
  include A #mixin
  def method2()  
     puts "method2 say hi"
  end
end
class C < B #inheritance
  def method3() 
     puts "method3 say hi"
  end
end

Давайте подивимось на вихід.

A.instance_methods(false)
  => [:method1]

A.instance_methods
  => [:method1]
B.instance_methods
 => [:method2, :method1, :nil?, :===, ...# ] # methods inherited from parent class, most important :method1 is also visible because we mix module A in class B

B.instance_methods(false)
  => [:method2]
C.instance_methods
  => [:method3, :method2, :method1, :nil?, :===, ...#] # same as above
C.instance_methods(false)
 => [:method3]

0

Щоб отримати лише власні методи та виключити успадковані:

Зсередини екземпляра:

self.methods - self.class.superclass.instance_methods

Ззовні:

TestClass.instance_methods - TestClass.superclass.instance_methods

Додайте його до класу:

class TestClass
  class << self
    def own_methods
      self.instance_methods - self.superclass.instance_methods
    end
  end
end

TestClass.own_methods
=> [:method1, :method2, method3]

(з рубіном 2.6.x)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.