Dapatkan daftar metode instance kelas


98

Saya ada kelas:

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

Bagaimana saya bisa mendapatkan daftar metode saya di kelas ini ( method1, method2, method3)?

Jawaban:


115

Anda benar-benar menginginkannya TestClass.instance_methods, kecuali jika Anda tertarik pada apa yang TestClassdapat dilakukannya.

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

Atau Anda dapat memanggil methods(tidak instance_methods) pada objek:

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

3
Heh, Anda mengalahkan saya dengan 47 detik. +1
— Phrogz

2
Ketika saya mencoba print TestClass.new.instance_methods, saya mendapatkan kesalahan inimy_class.rb:10:in <main>: undefined method instance_methods for #<TestClass:0x96b9d20> (NoMethodError)
— Vladimir Tsukanov

Anda hanya perlu melakukan TestClass.new.methods. Mungkin "itu" ambigu dalam jawaban saya.
— Andrew Grimm

Perhatikan bahwa di bawah Ruby 1.9+, larik nama metode adalah simbol, bukan string.
— Phrogz

1
@Phrogz: Ya, tetapi Anda diizinkan untuk menggunakan ekspresi reguler pada mereka. Anda bahkan tidak memanggil Cthulhu! :) Meskipun Anda akan mendapatkan [:method1]sebagai gantinya.
— Andrew Grimm

113
TestClass.methods(false) 

untuk mendapatkan hanya metode yang dimiliki kelas itu saja.

TestClass.instance_methods(false) akan mengembalikan metode dari contoh yang Anda berikan (karena mereka adalah metode instance TestClass).


2
Ini adalah cara yang bagus untuk menguji apakah suatu kelas memiliki metode polimorf dari kelas dasar Antarmuka-semu / Abstrak tanpa harus mencoba dan memanggil metode secara langsung.
— Daniel Doezema

2
Jawaban yang diterima memang bagus, tetapi yang ini kemungkinan akan membuat lebih banyak orang akan datang ke sini!
— Aaron

Ini pasti harus menjadi jawaban yang diterima. TERIMA KASIH!
— Vinicius Brasil

38
TestClass.instance_methods

atau tanpa semua metode yang diwariskan

TestClass.instance_methods - Object.methods

(Sebelumnya 'TestClass.methods - Object.methods')


25
atau tanpa metode diwariskan: TestClass.methods(false).
— sawa

2
@sawa TestClass.methods(false)kembali kosong
— Vladimir Tsukanov

1
Jawaban ini salah; hasilnya tidak akan termasuk method1,, method2atau method3, karena itu adalah metode dari instance kelas, bukan metode dari TestClassobjek itu sendiri.
— Phrogz

1
@Phrogz: Ups ... ya, 'TestClass.instance_methods - Object.methods', atau 'TestClass.new.methods - Object.methods' ... itu akan mengajari saya untuk tidak menjalankan konsol. Apakah yang terbaik bagi saya untuk menghapus jawaban ini, atau mengeditnya?
— Pavling

1
@Pavling Sunting jawaban Anda agar benar. (Cepat, sebelum OP memberikan kredit kepada orang lain! :)
— Phrogz

6

Anda bisa mendapatkan daftar yang lebih rinci (misalnya terstruktur dengan mendefinisikan kelas) dengan permata seperti debugging atau 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
Ini terlalu mirip dengan jawaban lain dan tidak menambahkan informasi atau kejelasan tambahan.
— Substansial

3
Anda gagal mengatakan bahwa ini juga sangat terlambat. : D
— Douglas G. Allen

2

Menurut instance_methods Ruby Doc

Mengembalikan larik yang berisi nama metode instance publik dan dilindungi di penerima. Untuk modul, ini adalah metode publik dan dilindungi; untuk kelas, mereka adalah metode instance (bukan tunggal). Jika parameter opsional salah, metode dari setiap leluhur tidak disertakan. Saya mengambil contoh dokumentasi resmi.

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

Mari kita lihat hasilnya.

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

Untuk hanya mendapatkan metode sendiri, dan mengecualikan yang diwariskan:

Dari dalam contoh:

self.methods - self.class.superclass.instance_methods

Dari luar:

TestClass.instance_methods - TestClass.superclass.instance_methods

Tambahkan ke kelas:

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

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

(dengan ruby ​​2.6.x)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.