Bir sınıfın örnek yöntemlerinin listesini alın


98

Sınıfım var:

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

Nasıl (bu sınıfta benim yöntemlerinin bir listesini alabilirsiniz method1, method2, method3)?

Yanıtlar:


116

Kendisinin neler yapabileceğiyle TestClass.instance_methodsilgilenmedikçe, gerçekten istiyorsun 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"]

Veya nesneyi çağırabilir methods( çağıramazsınız instance_methods):

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

3
Heh, beni 47 saniye geride bıraktın. +1
Phrogz

2
Denediğimde print TestClass.new.instance_methodsbu hatayı alıyorummy_class.rb:10:in <main>: undefined method instance_methods for #<TestClass:0x96b9d20> (NoMethodError)
Vladimir Tsukanov

Sadece yapman gerekiyor TestClass.new.methods. Belki cevabımda "o" belirsizdi.
Andrew Grimm

Ruby 1.9+ altında yöntem adları dizisinin dizeler değil semboller olduğunu unutmayın.
Phrogz

1
@Phrogz: Evet, ancak bunlar üzerinde normal ifadeler kullanmanıza izin verilmektedir. Cthulhu'yu bile çağırmıyorsun! :) Onun [:method1]yerine alırsınız .
Andrew Grimm

114
TestClass.methods(false) 

yalnızca o sınıfa ait olan yöntemleri almak için.

TestClass.instance_methods(false) Verdiğiniz örnekteki yöntemleri döndürür (çünkü bunlar TestClass'ın örnek yöntemleri).


2
Bu, bir sınıfın, yöntemleri doğrudan denemek ve çağırmak zorunda kalmadan sözde Arabirim / Soyut temel sınıftan çok biçimli yöntemlere sahip olup olmadığını test etmenin harika bir yoludur.
Daniel Doezema

2
Kabul edilen cevap harika ama bu muhtemelen daha fazla insanın buraya gelme sebebidir!
Aaron

Bu kesinlikle kabul edilen cevap olmalıdır. TEŞEKKÜRLER!
Vinicius Brasil

@Aaron: Bu cevap yanlış olduğundan şüpheliyim . bir nesnede çağırabileceğinizObject#methods yöntemleri döndürür . Bir nesnede çağırabileceğiniz yöntemler nelerdir? Sınıfında tanımlananlar . Hangi vasıta yapabilirsiniz yöntemleri listesini döndürür çağrı üzerine kendi sınıfında tanımlanan yöntemlerdir. Nedir bireyin sınıf? Öyle . Yani, size tanımlanan yöntemler verir , değil tanımlanır olanlar . Bu cevabın 116 olumlu oyu nasıl aldığından emin değilim, ne zaman bile olsaTestClass.methodsTestClassTestClassClassTestClass.methodsClassTestClass
Jörg W Mittag

… En uzaktan geçen bilgi, onu anında yanlış olarak algılayacaktır. Ya da bilirsiniz, sadece bu kodu kopyalayıp yapıştırmak ve çalıştırmak yanlış olduğunu ortaya çıkaracaktır.
Jörg W Mittag

39
TestClass.instance_methods

veya miras alınan tüm yöntemler olmadan

TestClass.instance_methods - Object.methods

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


25
veya olmayan yöntemler kalıtsal: TestClass.methods(false).
sawa

2
@sawa TestClass.methods(false)boş dönüyor
Vladimir Tsukanov

1
Bu cevap yanlış; sonuçlar içermez method1, method2veya method3bu yöntemleri olarak, örneklerde sınıfı, bir metotlarla TestClasskendisi nesne.
Phrogz

1
@Phrogz: Oops ... evet, 'TestClass.instance_methods - Object.methods' veya 'TestClass.new.methods - Object.methods' ... bana bir konsolu çalıştırmamamı öğretecek. Bu cevabı silmek mi yoksa düzenlemek benim için en iyisi mi?
Pavling

1
@Pavling Cevabınızı kesinlikle doğru olacak şekilde düzenleyin. (Operasyonel krediyi başka birine
atamadan

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

Ruby Doc instance_methods'a göre

Alıcıdaki genel ve korumalı örnek yöntemlerinin adlarını içeren bir dizi döndürür. Bir modül için bunlar halka açık ve korumalı yöntemlerdir; bir sınıf için bunlar örnek (tekil değil) yöntemleridir. İsteğe bağlı parametre yanlışsa, herhangi bir atanın yöntemi dahil edilmez. Resmi dokümantasyon örneğini alıyorum.

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

Çıktıya bakalım.

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]

1

Yalnızca kendi yöntemlerini almak ve devralınanları hariç tutmak için:

Örnek içinden:

self.methods - self.class.superclass.instance_methods

Dışarıdan:

TestClass.instance_methods - TestClass.superclass.instance_methods

Sınıfa ekleyin:

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

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

(yakut 2.6.x ile)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.